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