资讯专栏INFORMATION COLUMN

Java 实现线程死锁

sPeng / 3378人阅读

摘要:当两个并发线程访问同一个对象中的这个同步代码块时,一个时间内只能有一个线程得到执行。第三个例子同样适用其它同步代码块。也就是说,当一个线程访问的一个同步代码块时,它就获得了这个的对象锁。

概述

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

Synchronized关键字

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

当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。

以上规则对其它对象锁同样适用.

代码示例
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();
        }
    }
}
总结

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65489.html

相关文章

  • 超详细的Java面试题总结(二)之Java基础知识篇

    摘要:超详细的面试题总结一之基本知识多线程和虚拟机创建线程有几种不同的方式你喜欢哪一种为什么继承类实现接口应用程序可以使用框架来创建线程池实现接口。死亡线程方法执行结束,或者因异常退出了方法,则该线程结束生命周期。死亡的线程不可再次复生。 超详细的Java面试题总结(一)之Java基本知识 多线程和Java虚拟机 创建线程有几种不同的方式?你喜欢哪一种?为什么? 继承Thread类 实现R...

    wangjuntytl 评论0 收藏0
  • 实现死锁的两种方式以及ReentrantLock的额外功能

    摘要:实现死锁的方法有两种,一种是使用同步代码块,另一种是使用重入锁。但是如果调用带超时的方法,那么如果线程在等待时被中断,将抛出一个异常,这是一个非常有用的特性,因为它允许程序打破死锁。 思路: 死锁是指在多线程环境下的这么一种场景,两个(多个)线程在分别拿到自己的锁时尝试获取对方的锁,由于必须等待对方释放锁才能获取,然而双方谁也不肯先释放自己的锁, 导致双方谁都无法继续执行。通过一个实现...

    waltr 评论0 收藏0
  • Java线程学习(七)并发编程中一些问题

    摘要:相比与其他操作系统包括其他类系统有很多的优点,其中有一项就是,其上下文切换和模式切换的时间消耗非常少。因为多线程竞争锁时会引起上下文切换。减少线程的使用。很多编程语言中都有协程。所以如何避免死锁的产生,在我们使用并发编程时至关重要。 系列文章传送门: Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1) java多线程学习(二)syn...

    dingding199389 评论0 收藏0
  • Java线程学习(七)并发编程中一些问题

    摘要:因为多线程竞争锁时会引起上下文切换。减少线程的使用。举个例子如果说服务器的带宽只有,某个资源的下载速度是,系统启动个线程下载该资源并不会导致下载速度编程,所以在并发编程时,需要考虑这些资源的限制。 最近私下做一项目,一bug几日未解决,总惶恐。一日顿悟,bug不可怕,怕的是项目不存在bug,与其惧怕,何不与其刚正面。 系列文章传送门: Java多线程学习(一)Java多线程入门 Jav...

    yimo 评论0 收藏0
  • [Java并发-4]解决Java死锁的问题

    摘要:例如,张三同时申请账本和,账本管理员如果发现文件架上只有账本,这个时候账本管理员是不会把账本拿下来给张三的,只有账本和都在的时候才会给张三。但仍需注意的是,有时候预防死锁成本也是很高的。 在上一篇中,我们尝试使用了 Account.class作为互斥锁,来解决转账问题。但是很容易发现这样,所有的转账操作都是串行的,性能太差了。 让我们尝试提升下性能。 向现实世界要答案 现实世界中,转账...

    stonezhu 评论0 收藏0
  • 并发编程之死锁解析

    摘要:如何检测死锁由于死锁极难通过人工的方式查出来,因此提供了命令来检测某个进程中心线程的情况,并排查有没有死锁。线程持有的锁,等待的锁。避免出现死锁,如果出现了死锁,则可以使用命令查看线程是否有死锁。 showImg(https://segmentfault.com/img/remote/1460000014936757); 前言 在 Java 的并发编程中,有一个问题需要特别注意,那就是...

    yy736044583 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<