因为看到了LockSupport能够使线程进入阻塞状态,就想了一下还有什么方法能够使线程进入阻塞状态吗?因为我记忆里只有拿不到锁的时候才会进入阻塞状态
搜了一下引发线程进入阻塞的方法
网上有这样说:
(1)线程睡眠:Thread.sleep (long millis)方法,使线程转到阻塞状态。
(2)线程等待:Object类中的wait()方法,
(3)线程礼让,Thread.yield() 方法
(4)线程自闭,join()方法,
(5)suspend() 和 resume() 方法
以上方法可能使阻塞线程,但我认为只有进入了阻塞状态才能被认为是阻塞了线程,可能是我太钻牛角尖了,我觉得这样的说法是有点偏颇的,因为我脑海里记忆的是下面的一张图:
但又有没有可能是书上错了呢?
那就来试试吧
1.sleep()方法
public static void main(String[] args) {
new Thread(()->{
try {
System.out.println("正在睡眠");
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t1").start();
}
使用jps查看线程
使用jstack查看线程状态:
哦豁,TimeWaiting,线程处于超时等待状态
2. wait 方法
Object o = new Object();
Thread t2 = new Thread(() -> {
synchronized (o) {
try {
System.out.println("执行等待!");
o.wait();
} catch (InterruptedException e) {
}
}
}, "t2");
t2.start();
Thread.sleep(100000);
o.notify();
waitting状态
3.synchronized(出现阻塞状态)
Object o = new Object();
new Thread(() -> {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o) {
}
}, "t1").start();
//让t2 先拿到锁,然后就一直处于wait状态,我们再来观察t1
new Thread(() -> {
synchronized (o) {
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t2").start();
4. join
Thread t1 = new Thread(() -> {
try {
Thread.sleep(10000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t1");
t1.start();
//先让t1 跑起来 观察t2
Thread.sleep(10);
Thread t2 = new Thread(() -> {
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t2");
t2.start();
5.yield
让出CPU时间片的方法,有点不好操作,因为让出一个时间片的太短了啊
以后想到方法了再来更新
6.LockSupport
Thread t1 = new Thread(() -> {
LockSupport.park();
}, "t1");
t1.start();
Thread.sleep(100000);
LockSupport.unpark(t1);
结论:
最后一个LockSupport就把之前的所有可以推翻:只有进入阻塞状态才能称为阻塞线程
可能这一部分定义得不是特别明确,就不深究了,了解就行了,日常开发应该也用不到这一部分的知识,理解就行;
还有如果要阻塞线程:
以上除了yield 其他的都可以起到阻塞线程的作用,而不是让线程进入java定义的阻塞线程状态