我们知道线程池是靠阻塞队列实现的,那么这个阻塞队列是具体如何实现阻塞的呢?
说到阻塞我们能想到线程的sleep和Object类的wait方法,seep是让线程睡眠若干秒再去执行,而wait是让线程休眠如果不通知线程恢复,那么线程将一直休眠下去不进行任何操作。
所以我们想到的一个办法是通过wait和notify方法休眠和恢复休眠线程实现阻塞和恢复
final Object obj = new Object();
Thread A = new Thread(new Runnable() {
@Override
public void run() {
int sum = 0;
for(int i=0;i<10;i++){
sum+=i;
}
try {
synchronized (obj){
System.out.println("当前线程开始堵塞!");
obj.wait();
System.out.println("堵塞结束!");
}
}catch (Exception e){
e.printStackTrace();
}
System.out.println(sum);
}
});
A.start();
//睡眠一秒钟,保证线程A已经计算完成,阻塞在wait方法
Thread.sleep(1000);
synchronized (obj){
obj.notify();
}
输出日志如下:
当前线程开始堵塞!
堵塞结束!
45
下面说一种更简单的办法LockSupport,这个方法也是线程池阻塞队列使用的方法
Thread A = new Thread(new Runnable() {
@Override
public void run() {
int sum = 0;
for(int i=0;i<10;i++){
sum+=i;
}
System.out.println("开始阻塞!");
LockSupport.park();
System.out.println("结束阻塞!");
System.out.println(sum);
}
});
A.start();
//睡眠一秒钟,保证线程A已经计算完成,阻塞在wait方法
Thread.sleep(1000);
LockSupport.unpark(A);