Java线程池深入理解(3)

  如果当前线程池处于RUNNING状态,则需要再次检查线程池(因为可能在上次检查后,有线程资源被释放),是否有空闲的线程;如果有则执行该任务;

3、如果不能将任务放入阻塞队列中,说明阻塞队列已满;那么将通过addWoker()尝试创建一个新的线程去执行这个任务;如果addWoker()执行失败,说明线程池中线程数达到maxPoolSize,则执行reject()处理任务;

 

sumbit()内部实现

会将提交的Callable任务会被封装成了一个FutureTask对象

FutureTask类实现了Runnable接口,这样就可以通过Executor.execute()提交FutureTask到线程池中等待被执行,最终执行的是FutureTask的run方法;

比较:

两个方法都可以向线程池提交任务,execute()方法的返回类型是void,它定义在Executor接口中, 而submit()方法可以返回持有计算结果的Future对象,它定义在ExecutorService接口中,它扩展了Executor接口,其它线程池类像ThreadPoolExecutor和ScheduledThreadPoolExecutor都有这些方法。

 

总结executor() vs submit():

(1)execute()方法实际上是Executor中声明的方法,在ThreadPoolExecutor进行了具体的实现,这个方法是ThreadPoolExecutor的核心方法,通过这个方法可以向线程池提交一个任务,交由线程池去执行。

(2)submit()方法是在ExecutorService中声明的方法,在AbstractExecutorService就已经有了具体的实现,在ThreadPoolExecutor中并没有对其进行重写,这个方法也是用来向线程池提交任务的,但是它和execute()方法不同,它能够返回任务执行的结果,去看submit()方法的实现,

会发现它实际上还是调用的execute()方法,只不过它利用了Future来获取任务执行结果。

 

八.线程池的关闭

ThreadPoolExecutor提供了两个方法,用于线程池的关闭,分别是shutdown()和shutdownNow(),其中:

  shutdown():不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务

  shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务

 

九.实现

import org.junit.Test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
 
 
public class TestExecutor {
    @Test
    public void testSingleThreadExecutorPool() {
        ExecutorService pool = Executors.newSingleThreadExecutor();
        Thread t1 = new MyThread();
        Thread t2 = new MyThread();
        Thread t3 = new MyThread();
        Thread t4 = new MyThread();
        Thread t5 = new MyThread();
        pool.execute(t1);
        pool.execute(t2);
        pool.execute(t3);
        pool.execute(t4);
        pool.execute(t5);
        pool.shutdown();
        /*
        pool-1-thread-1正在执行...
        pool-1-thread-1正在执行...
        pool-1-thread-1正在执行...
        pool-1-thread-1正在执行...
        pool-1-thread-1正在执行...
        */
    }
 
    @Test
    public void testFixThreadExecutorPool() {
        //创建一个可重用固定线程数的线程池
        ExecutorService pool = Executors.newFixedThreadPool(2);
 
        //创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口
        Thread t1 = new MyThread();
        Thread t2 = new MyThread();
        Thread t3 = new MyThread();
        Thread t4 = new MyThread();
        Thread t5 = new MyThread();
 
        //将线程放入池中进行执行
        pool.execute(t1);
        pool.execute(t2);
        pool.execute(t3);
        pool.execute(t4);
        pool.execute(t5);
 
        //关闭线程池
        pool.shutdown();
        /*
        *pool-1-thread-1正在执行...
        *pool-1-thread-2正在执行...
        *pool-1-thread-1正在执行...
        *pool-1-thread-2正在执行...
        *pool-1-thread-1正在执行...
        */
    }
 
    @Test
    public void testCachedThreadExecutorPool() {
        //创建一个可重用固定线程数的线程池
        ExecutorService pool = Executors.newCachedThreadPool();
 
        //创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口
        Thread t1 = new MyThread();
        Thread t2 = new MyThread();
        Thread t3 = new MyThread();
        Thread t4 = new MyThread();
        Thread t5 = new MyThread();
 
        //将线程放入池中进行执行
        pool.execute(t1);
        pool.execute(t2);
        pool.execute(t3);
        pool.execute(t4);
        pool.execute(t5);
 
        //关闭线程池
        pool.shutdown();
        /*
        pool-1-thread-1正在执行...
        pool-1-thread-2正在执行...
        pool-1-thread-1正在执行...
        pool-1-thread-3正在执行...
        pool-1-thread-1正在执行...
        */
    }
 
    @Test
    public void testScheduledThreadPoolExecutor() {
        ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
 
        exec.scheduleAtFixedRate(new Runnable() {//每隔一段时间就触发异常
            public void run() {
                System.out.println("================");
            }
        }, 1000, 5000, TimeUnit.MILLISECONDS);
 
        exec.scheduleAtFixedRate(new Runnable() {//每隔一段时间打印系统时间,证明两者是互不影响的
            public void run() {
                System.out.println(System.nanoTime());
            }
        }, 1000, 2000, TimeUnit.MILLISECONDS);
    }
    /**
    ================
    440697961331385
    440699965178923
    440701962726589
    ================
    440703964380898
    440705963957505
    ================
    440707961439581
    440709966042376
    440711964335904
    ================
    */
}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/72f3ba9e30658119eb612feebb6006a6.html