Java 实现线程死锁

时间:2022-04-29
本文章向大家介绍Java 实现线程死锁,主要内容包括Java 实现线程死锁、概述、Synchronized关键字、代码示例、总结、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

Java 实现线程死锁

概述

春节的时候去面试了一家公司,笔试题里面有一道是使用简单的代码实现线程的‘死锁’,当时没有想到这道题考的是Synchronized关键字,于是自己定义了两个资源模拟了一下。后面想想肠子都悔青了,于是自己在电脑上敲了一遍,同时也是对自己的一个提醒,基础功夫还不够扎实。

Synchronized关键字

Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。

  1. 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
  2. 然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
  3. 尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
  4. 第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
  5. 以上规则对其它对象锁同样适用.

代码示例

package test160118;

public class TestSynchronized {
    public static void main(String[] args) {
        Sy sy = new Sy(0);
        Sy sy2 = new Sy(1);
        sy.start();
        sy2.start();
    }
}

class Sy extends Thread {
    private int flag ;

    static Object x1 = new Object();
    static Object x2 = new Object();

    public Sy(int flag) {
        this.flag = flag;
    }
    @Override
    public void run() {
        System.out.println(flag);
        try {
            if (flag == 0) {
                synchronized (x1) {
                    System.out.println(flag+"锁住了x1");
                    Thread.sleep(1000);
                    synchronized (x2) {
                        System.out.println(flag+"锁住了x2");
                    }
                    System.out.println(flag+"释放了x1和x2");
                }
            }
            if(flag == 1) {
                synchronized (x2) {
                    System.out.println(flag+"锁住了x2");
                    Thread.sleep(1000);
                    synchronized (x1) {
                        System.out.println(flag+"锁住了x1");
                    }
                    System.out.println(flag+"释放了x1和x2");
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

总结

总之说多了都是泪,关键不是我不会而是我没有想到它考的都是这个。也不知道面试过没过,有点方。后面会陆陆续续把之前面试时答得不是很好的几道题写成专栏的。