美文网首页
Java 线程

Java 线程

作者: 寇夏寇夏 | 来源:发表于2017-05-23 14:24 被阅读0次

线程

<code>java<code> 创建线程最简单的方式就是继承<code>Thread</code>类或者实现 <code>Runnable</code>接口实现 <code>run()</code> 方法,然后调用 <code>start()</code> 方法来让线程执行。

public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread());
            }
        }).start();
    }

输出:

Thread[Thread-0,5,main] 这个是输出的是线程名,线程优先级以及线程组的名字,具体可以看<code>Thread</code> 的<code>toString()</code> 方法

实际上 实现 Runnable 接口的类可以看做是一个任务(<code>task</code>)真正创建线程的是 <code>Thread</code>类

线程池

JDK 中提供了 Executor 框架来创建线程池。
其中 <code>Executors</code>作为工厂类 提供了几个创建线程的工厂方法

public class ThreadTest {

    public static void main(String[] args) {
        TestTask tt = new TestTask();
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for (int i = 0; i <10;i++){
            executorService.submit(tt);
        }
    }

}

class TestTask implements Runnable {

    @Override
    public void run() {
        System.out.println(System.currentTimeMillis() + " Thread ID:" + Thread.currentThread().getId());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

输出:

1495507701904 Thread ID:10
1495507701905 Thread ID:11
1495507701904 Thread ID:9
1495507701905 Thread ID:12
1495507701905 Thread ID:13
1495507702909 Thread ID:9
1495507702909 Thread ID:12
1495507702909 Thread ID:11
1495507702909 Thread ID:13
1495507702909 Thread ID:10

<code>newFixedThreadPool(int nThreads)</code> 接收一个 <code>int</code> 参数,返回一个固定大小的线程池,上面代码的输出可以看出十个任务提交到线程池中,前5个和后面的5个执行相差了1秒。
如果换成<code>newCachedThreadPool()</code>来创建线程池则会得到如下输出:

1495508104585 Thread ID:9
1495508104586 Thread ID:10
1495508104586 Thread ID:11
1495508104586 Thread ID:12
1495508104586 Thread ID:13
1495508104586 Thread ID:14
1495508104587 Thread ID:15
1495508104587 Thread ID:16
1495508104587 Thread ID:17
1495508104587 Thread ID:18

线程池的核心

<code>Executors</code> 提供这些工厂方法都是通过<code>ThreadPoolExecutor</code>来实现
<code>ThreadPoolExecutor</code>中提供了四个构造方法,而其他三个都是通过下图这个构造方法来实现。


jdk 源码上提供的注释说明

/**
    * Creates a new {@code ThreadPoolExecutor} with the given initial
    * parameters.
    *
    * @param corePoolSize the number of threads to keep in the pool, even
    *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
    * @param maximumPoolSize the maximum number of threads to allow in the
    *        pool
    * @param keepAliveTime when the number of threads is greater than
    *        the core, this is the maximum time that excess idle threads
    *        will wait for new tasks before terminating.
    * @param unit the time unit for the {@code keepAliveTime} argument
    * @param workQueue the queue to use for holding tasks before they are
    *        executed.  This queue will hold only the {@code Runnable}
    *        tasks submitted by the {@code execute} method.
    * @param threadFactory the factory to use when the executor
    *        creates a new thread
    * @param handler the handler to use when execution is blocked
    *        because the thread bounds and queue capacities are reached
    * @throws IllegalArgumentException if one of the following holds:<br>
    *         {@code corePoolSize < 0}<br>
    *         {@code keepAliveTime < 0}<br>
    *         {@code maximumPoolSize <= 0}<br>
    *         {@code maximumPoolSize < corePoolSize}
    * @throws NullPointerException if {@code workQueue}
    *         or {@code threadFactory} or {@code handler} is null
    */

<code> corePoolSize </code> 指定线程池中保持的线程数量,即使他们是空闲的,除非设置了<code>allowCoreThreadTimeOut</code>

<code> maximumPoolSize </code> 指定线程池允许创建的最大线程数量

<code> keepAliveTime </code> 当线程池中的线程数量大于<code> corePoolSize </code>设置的数量时,大于<code> corePoolSize </code>数量的那部分线程等待新任务的最大等待时间,当超过这个时间多出来的线程将会被销毁。

<code> unit </code> <code> keepAliveTime </code>的时间单位

<code> workQueue </code> 用于保存通过 <code>execute</code> 方法提交并且未来得及执行的任务。

<code> threadFactory </code> 用来创建线程的线程工厂
<code> handler </code> 当线程池中线程数量到达极限并且 workQueue达到最大容量时 处理任务的拒绝策略

workQueue传入的是一个 <code>BlockingQueue</code>类型的参数,用于保存 Runnable 对象

可使用的<code>BlockingQueue</code>有:
<code>SynchronousQueue</code> 直接提交的队列
<code>ArrayBlockingQueue</code> 有界队列
<code>LinkedBlockingQueue</code> 无界队列
<code>PriorityBlockingQueue</code> 优先级队列

<code>handler</code>
有四种拒绝策略
<code>AbortPolicy</code> 直接抛出异常
<code>DiscardPolicy</code> 默默抛弃
<code>DiscardOldestPolicy</code> 丢弃最老的任务,也就是即将执行的任务
<code>CallerRunsPolicy</code> 在调用线程中执行

相关文章

网友评论

      本文标题:Java 线程

      本文链接:https://www.haomeiwen.com/subject/abywxxtx.html