在上一章中介绍了使线程进入timed_waiting状态的3种办法

1. Thread.sleep(long)2. Object.wait(long)3. Thread.join(long)

接下来持续实战使线程进入BLOCKED状态的办法

synchronized会使线程进入BLOCKED状态

/** * synchronized线程处于timed_waiting状态 * * @author jinglei * @date 2020/8/21 13:09 */public class TimedWaitingBySync {    private static Object lock = new Object();    public static void main(String[] args) {        Thread syncLongThread = new Thread(new Runnable() {            @Override            public void run() {                synchronized (lock){                    System.out.println("子线程无奈进入同步代码块");                }            }        });        syncLongThread.setName("mythread-sync");        //启动线程        syncLongThread.start();        //留神,这个中央并不一定会保障主线程优先于子线程执行,具体哪个线程先执行是由CPU依据过后的系统资源调度的,        // 只管大部分状况可能看到是主线程优先执行        synchronized (lock){            while(true){            }        }    }}

依照如下步骤查看线程堆栈

堆栈内容如下

能够看出线程进入了BLOCKED状态,并且是在一个对象锁或者是对象监视器上阻塞,当前看到这种日志就是阐明此线程须要获取一个对象锁,然而这个锁曾经被其余线程占有了,该线程只能进入阻塞队列期待其余线程开释锁。

谈到synchronized就不得不说下经典的死锁问题,死锁指的是两个及其以上线程在别离持有了相应的锁的同时,还须要对方曾经持有的锁,并且本身曾经持有的锁不会被动去开释,此时就造成了一个死循环,也就是死锁。

现实生活中的例子,比方有一双筷子,李梅和韩雷雷别离领有了一根筷子,他们都不会把本人的筷子给他人还想要对方的筷子,这就形成了死锁。

废话不持续了,上代码

/** * sync导致的死锁 * * @author jinglei * @date 2020/8/24 16:22 */public class SyncDeadLock {    private static Object tLock = new Object();    private static Object sLock = new Object();    static class Teacher implements Runnable{        @Override        public void run() {            synchronized (tLock){                System.out.println("老师持有了tLock锁,还须要获取sLock锁");                try {                    //休眠1秒为了让Student有工夫去获取sLock锁                    Thread.sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                synchronized (sLock){                    System.out.println("老师更新问题");                }            }        }    }    static class Student implements Runnable {        @Override        public void run() {            synchronized (sLock){                System.out.println("学生持有了sLock锁,还须要获取tLock锁");                synchronized (tLock){                    System.out.println("学生更新问题");                }            }        }    }    public static void main(String[] args) {        new Thread(new Teacher()).start();        new Thread(new Student()).start();    }}

咱们创立了两个线程Teacher和Student,这两个线程执行run办法须要获取两把锁
Teacher先获取tLock,再去获取sLock
Student先获取sLock,再去获取tLock
在Teacher的run办法中有句Thread.sleep(1000);是为了让Teacher让出cpu以保障Student获取sLock锁,从而造成死锁条件。

程序运行后,获取堆栈信息

堆栈如下图

能够看出Thread-1也就是Student线程曾经获取了锁0x000000076bee60c8,在期待0x000000076bee60b8
Thread-0也就是Teacher获取了0x000000076bee60b8,在期待0x000000076bee60c8。
从而造成了死锁场面