死锁案例分析

news/2024/5/20 12:10:19 标签: 线程, 死锁

死锁的产生以及解决办法,看代码分析,注意里边的注释,自行运行。

package thread;

/**
 * 模拟买票
 * 
 * @author yhl
 * 
 */

class Thread02 implements Runnable{
    private static int countTraket = 100;
    public boolean flag = true;
    private  Object mutex  = new Object();
    @Override
    public void run() {
        if (flag) {
            while (true) {
                synchronized (mutex) {
                    // 锁(同步代码块)在什么时候释放? 代码执行完, 自动释放锁.
                    // 如果flag为true 线程1 先拿到 obj锁,在拿到this 锁、 才能执行。
                    // 如果flag为false 线程2 先拿到this,在拿到obj锁,才能执行。
                    // 死锁的产生:同步中嵌套同步,互不释放。
                    // 死锁解决办法:不要在同步中嵌套同步。
                    sale();
                }
            }
        } else {
            while (true) {
                sale();
            }
        }

    }

    //同步代码块
    public void sale(){
        synchronized(mutex){
            if(countTraket>0){
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("当前线程:"+Thread.currentThread().getName()+";正在买第"+(100-countTraket+1)+"张票。");
                countTraket--;
            }
        }
    }

    //同步函数
    public synchronized void sale1(){
        if(countTraket>0){
            System.out.println("当前线程:"+Thread.currentThread().getName()+";正在买第"+(100-countTraket+1)+"张票。");
            countTraket--;
        }
    }
    public static synchronized void sale2(){
        if(countTraket>0){
            System.out.println("当前线程:"+Thread.currentThread().getName()+";正在买第"+(100-countTraket+1)+"张票。");
            countTraket--;
        }
    }

}
public class ThreadDemo1 {

    public static void main(String[] args) throws InterruptedException {

        Thread02 t  = new Thread02();
        Thread t1 = new Thread(t,"窗口1");
        Thread t2 = new Thread(t,"窗口2");
        t1.start();
        Thread.sleep(50);
        t.flag=false;
        t2.start();
    }
}

http://www.niftyadmin.cn/n/1368466.html

相关文章

多线程有三大特性和Java内存模型

三大特性: 原子性、可见性、有序性 什么是原子性 即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。 一个很经典的例子就是银行账户转账问题: 比如从账户A向账户B转1000元,那么必然包括2个操作&#…

volatile与synchronized区别

仅靠volatile不能保证线程的安全性。(原子性) 1.volatile轻量级,只能修饰变量。synchronized重量级,还可修饰方法 2.volatile防止重排序。 要理解这个问题,先要了解对象的构造过程,实例化一个对象其实可…

synchronized—生产者与消费者线程实例分析

先看几个概念,实例里边主要是通过wait和notify来实现的。 wait()、notify()、notifyAll()是三个定义在Object类里的方法,可以用来控制线程的状态。 这三个方法最终调用的都是jvm级的native方法。随着jvm运行平台的不同可能有些许差异。 如果对象调用了…

锁的两个基本工具—synchronized和Lock

1.ReentrantLock 与synchronized有相同的并发性和内存语义,还包含了中断锁等候和定时锁等候,意味着线程A如果先获得了对象obj的锁,那么线程B可以在等待指定时间内依然无法获取锁,那么就会自动放弃该锁。2.但是由于synchronized是在…

LinK3D论文详解

摘要 特征提取和匹配是许多计算机视觉任务的基本部分,例如二维或三维物体检测、识别和配准。众所周知,二维特征提取和匹配已经取得了很大的成功。遗憾的是,在3D领域,由于描述能力差和效率低,目前的方法无法支持3D激光雷…

BlockingQueue—生产者消费者实例

在看实例代码之前,先普及一点相关的知识点: BlockingQueue即阻塞队列,从阻塞这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞。被阻塞的情况主要有如下两种:1. 当队列满了的时候进行入队列操作2. 当队列空…

重入锁学习—synchronized和ReentrantLock

锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLock等等 ) 。这些已经写好提供的锁为我们开发提供了便利。 重入锁,也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层…

activeMQ之消息过滤

这两天在看activeMQ,之前用到过,但是没有很系统的去学习,今天看到里边有个消息过滤,之前不了解,这次记录下来,后续有其他的还会再补充。 1、发送消息放入特殊标志: message.setStringProperty(name, value…