多线程死锁

摘要:
不嵌套同步publicclassDemo06DeadLock{publicstaticvoidmain(String[]args){//创建线程任务对象Ticketticket=newTicket();Thread3=newThread(ticket,“Window 3”);}staticassTicketimplementsRunnable{Objectobj=newObject();

多线程死锁:同步中嵌套同步,导致锁无法释放

死锁解决办法:不要在同步中嵌套同步

public class Demo06DeadLock {
    public static void main(String[] args) {
        //创建线程任务对象
        Ticket ticket = new Ticket();
        //创建三个窗口对象
        Thread t1 = new Thread(ticket, "窗口1");
        Thread t2 = new Thread(ticket, "窗口2");
        Thread t3 = new Thread(ticket, "窗口3");
        //卖票
        t1.start();
        t2.start();
        t3.start();
    }

    static class Ticket implements Runnable {
        Object obj = new Object();
        private int ticket = 100;

        public void run() {
            String name = Thread.currentThread().getName();
            while (true) {
                if ("窗口1".equals(name)) {
                    synchronized (obj) {
                        sell(name);
                    }
                } else {
                    sell(name);
                }
                if (ticket <= 0) {
                    break;
                }
            }
        }

        private synchronized void sell(String name) {
            synchronized (obj) {
                if (ticket > 0) {
                    System.out.println(name + "卖票:" + ticket);
                    ticket--;
                }
            }
        }
    }
}

同步方法的同步锁是谁:

1、对于非static方法,同步锁就是this。

2、对于static方法,我们使用当前方法所在类的字节码对象(类名.class)。

分析:

同步代码块的锁是obj,同步方法的锁是this,窗口1先获取obj,再获取this,再获取obj,即窗口1要三次获取锁。窗口2和窗口3先获取this,再获取obj,当窗口1获取了obj后等待this,而窗口2获取了this而等待obj,此时出现了死锁。

结果为:

多线程死锁第1张

 买到第14张票时,程序为继续卖票也未停止执行。

再次运行,会出现如下结果:只卖1张票,程序就不再继续卖票且未结束。

多线程死锁第2张

 网络上关于死锁的内容:

所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。

因此我们举个例子来描述,如果此时有一个线程A,按照先锁a再获得锁b的的顺序获得锁,而在此同时又有另外一个线程B,按照先锁b再锁a的顺序获得锁。如下图所示:

多线程死锁第3张

免责声明:文章转载自《多线程死锁》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇深入理解javascript原型和闭包(5)——instanceof如何修改数据库密码下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

轻量级锁,偏向锁,重量级锁

轻量级锁,偏向锁,重量级锁 参考视频:https://www.bilibili.com/video/BV16J411h7Rd 对象头信息: normal,正常对象,使用markwork的最后3bits来标记,001就表示正常对象 Biased,偏向锁标记,使用markwork的最后3bits来标记,跟正常对象虽然有区别,但区别不大,101就表示偏向锁...

流式处理框架storm浅析(上篇)

本文来自网易云社区 作者:汪建伟 前言 前一段时间参与哨兵流式监控功能设计,调研了两个可以做流式计算的框架:storm和spark streaming,我负责storm的调研工作。断断续续花了一周的时间看了官网上的doc和网络上的一些资料。我把所学到的总结成一个文档,发出来给对storm感兴趣的同事做入门引导。 storm背景 随着互联网的更进一步发...

delphi TTcpClient TTcpServer分析

http://blog.csdn.net/andrew57/article/details/8767308 只描述windows socket部分。 sockets.pas中各个类得继承关系: TBaseSocket | ------------------------ | TIpSocket | -----------------------------...

Java多线程之控制执行顺序

 概念: 多线程在并发环境中的正常执行顺序是随机无序的,并不能按照期盼的结果输出。                因为启动一个线程时,线程并不会立即执行,而是等待CPU的资源调度,CPU能调度哪个线程,是通过多种复杂的算法计算而来。 (一)Thread的join()方法来解决这个问题        一般在多线程编程时,需要控制线程的先后执行顺序,比如:主线...

将dll文件注入到其他进程中的一种新方法

http://www.45it.com/windowszh/201212/33946.htm http://www.hx95.cn/Article/OS/201212/65095.html 我们知道将动态连接库注入到其他进程中有很多种方法。最常见的方法是使用钩子函数(Hook),但是这种方法主要有两个缺点:第一如果某个进程没有加载User32.dll,那么...

基础概念——C标准、C运行库和glibc

C标准:C 标准主要由两部分组成,一部分描述C的语法,另一部分描述C标准库(描述了一些C标准函数的原型,但是不提供实现)。C标准库定义了一组标准头文件,每个头文件中包含一些相关的函数、变量、类型声明和宏定义。 常见的C标准就是ANSI C;美国国家标准协会;为了提高C语言的开发效率,C标准定义了一系列常用的函数,称为C标准库函数。应用程序开发者可以包含这些...