1.最简单的线程的使用
new Thread() {
@Override
public void run() {
// 业务逻辑
}
}.start();
但这确存在着很多问题:
1、首先频繁的创建、销毁对象是一个很消耗性能的事情;
2、如果用户量比较大,导致占用过多的资源,可能会导致我们的服务由于资源不足而宕机;
综上,在实际的开发中,这种操作十分不可取。
2.线程池的优点及作用
-
提升系统的性能以及使用率,减少对象的创建与销毁。
-
可以控制线程数,有效的提升服务器的使用资源,避免由于资源不足而发生宕机等问题。
3.线程池的四种使用方式
3.1newCachedThreadPool
如果线程池中的线程数量过大,它可以有效的回收多余的线程,如果线程数不足,那么它可以创建新的线程,线程池中的线程数不受限制
缺点:当业务处理时间过长时,会自动的创建线程进行执行其他代码,不可控。
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
final int index = i;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
executor.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " " + index);
}
});
}
3.2 newFixedThreadPool
可以自动控制线程池中的线程数,避免不必要的性能消耗。
ExecutorService executor = Executors.newFixedThreadPool(5); //设置线程池最大容量
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
final int index = i;
executor.execute(() -> {
try {
Thread.sleep(2 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + index);
});
}
executor.shutdown();
3.3 newScheduledThreadPool
- 该线程池支持定时,以及周期性的任务执行。
- 如果业务执行时间结束,但是线程池设置的间隔时间还没到,不会继续进行,会进行等待。
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2); //初始化线程池中的线程个数
executor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
long start = new Date().getTime();
System.out.println("scheduleAtFixedRate 开始执行时间:" +
DateFormat.getTimeInstance().format(new Date()));
try {
Thread.sleep(1000); //业务执行时间
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = new Date().getTime();
System.out.println("scheduleAtFixedRate 执行花费时间=" + (end - start) / 1000 + "m");
System.out.println("scheduleAtFixedRate 执行完成时间:" + DateFormat.getTimeInstance().format(new Date()));
System.out.println("======================================");
}
}, 1, 5, TimeUnit.SECONDS); //1 延迟多久开始进行; 2 时间间隔
3.4 newSingleThreadExecutor
单线程池,至始至终都由一个线程来执行。
ExecutorService executor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 5; i++) {
final int index = i;
executor.execute(() -> {
try {
Thread.sleep(2 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + index);
});
}
executor.shutdown();