创建线程

2020-06-15  本文已影响0人  MisAutumn
1. 继承Thread类,重写run方法

继承一个类消耗更大

2. 实现runnable接口,重写run方法
3. 实现callable接口,重写call方法,有返回值
t.start()    异步执行,启动新线程
t.run()      同步执行
t.isAlive()  判断线程是否存活
4.创建线程池

1. fixedThreadPool
一个指定工作线程数量的线程池。每提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。
优点:降低创建线程所耗开销。
缺点:不被使用的线程不会被释放,占用系统资源。

ExecutorService service = Executors.newFixedThreadPool(5);
for (int i = 0; i < 6; i++) {
    service.execute(() -> {
        try {
            TimeUnit.MILLISECONDS.sleep(500);
        } catch(InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName());
    });
}
System.out.println(service);
service.shutdown(); // 等所有任务执行完才会关闭
System.out.println(service.isTerminated());
System.out.println(service.isShutdown());
System.out.println(service);
        
TimeUnit.SECONDS.sleep(5);
System.out.println(service.isTerminated());
System.out.println(service.isShutdown());
System.out.println(service);

输出:

java.util.concurrent.ThreadPoolExecutor@7229724f[Running, pool size = 5, active threads = 5, queued tasks = 1, completed tasks = 0]
false
true
java.util.concurrent.ThreadPoolExecutor@7229724f[Shutting down, pool size = 5, active threads = 5, queued tasks = 1, completed tasks = 0]
pool-1-thread-4
pool-1-thread-1
pool-1-thread-2
pool-1-thread-5
pool-1-thread-3
pool-1-thread-4
true
true
java.util.concurrent.ThreadPoolExecutor@7229724f[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 6]

2. cachedThreadPool

  1. 工作线程的创建数量没有限制(最多为Interger. MAX_VALUE), 可灵活的往线程池中添加线程。
  2. 如果某个工作线程空闲了指定的时间(默认为1分钟),则该工作线程将自动终止。终止后,如果又提交了新的任务,则线程池重新创建一个工作线程。
  3. 要注意控制任务的数量,否则,由于大量线程同时运行,很有会造成系统瘫痪。
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

3. singleThreadPool
同一时间只能有一个线程工作,确保程序顺序执行。

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

4. scheduleThreadPool
可以设置线程数量,支持定时及周期性执行任务。

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);

为什么不推荐使用Executors

LinkedBlockingQueue是一个无边界队列,对于一个无边界队列来说,是可以不断的向队列中加入任务的,这种情况下就有可能因为任务过多而导致内存溢出的问题。
自定义BlockingQueue限制任务队列长度,长度超出后会抛出java.util.concurrent.RejectedExecutionException
LinkedBlockingQueue 无界队列
ArrayBlockingQueue 有界队列,可限制大小

ExecutorService executor = new ThreadPoolExecutor(10, 10,
                                                  60L, 
                                                  TimeUnit.SECONDS,
                                                  new ArrayBlockingQueue(10));

参考

上一篇下一篇

猜你喜欢

热点阅读