JAVA中关于同步与死锁的问题
java中当多个现成同时操纵同一资源的时候需要考虑同步的问题。如车站售票,不同售票点卖同一班次车票的时候就要同步,否则卖票会有问题。下面代码模拟车站卖票:
- class TicketSeller implements Runnable
- {
- public int ticket = 20;
- public void run()
- {
- for(int i = 0; i < 100; i++)
- {
- synchronized(this)
- {
- if(this.ticket-- >0)
- {
- Utilities.sleep(300);
- System.out.println(Thread.currentThread().getName() + "卖出一张票,余票:" + (this.ticket) + "张");
- }
- }
- }
- }
- }
- class Utilities
- {
- public static void sleep(int timeSpan)
- {
- try
- {
- Thread.sleep(timeSpan);
- }
- catch (Exception e)
- {
- }
- }
- }
- class Hello
- {
- public static void main(String[] args)
- {
- TicketSeller ts = new TicketSeller();
- Thread tl = new Thread(ts,"铜梁站");
- Thread bs = new Thread(ts,"璧山站");
- Thread spb = new Thread(ts,"沙坪坝站");
- tl.start();
- bs.start();
- spb.start();
- }
- }
输出结果:
但有时过多的使用同步会造成程序性能下降。除此之外过多同步还会发生更严重的后果:死锁。
也就是说,同步代码块中都去争夺同一资源,互不相让。举个例子,在一条东西方向的狭窄的巷道中,AB两车相遇,互补退让,结果是两个车都走不了,这就是死锁。这里隐含了一个情景就是,A车占有东边这一段道路,它需要B车让出B车占有西边的道路,而同时B车占有西边的道路,它需要A车让出A车所占有的西边的道路。两车各自占有各自的资源,且同时争夺对方占有的资源,互补相让,就造成了死锁。
这里,为了更好的阐述并模拟JAVA中死锁的情况。我再举一个例子:
小红和小明马上就要毕业了,都在准备毕业论文的撰写。他们的论文都要用到两本书,一本是《汇编语言》,另一本是《算法导论》。他们都要去图书馆借阅这两本书,但图书馆规定某一人一次只能借阅1本书。于是小红借了《汇编原理》,小明借了《算法导论》。过了一段时间后,他们论文都完成了一 半。此时,小红需要小明手中的《算法导论》,同时小明也要小红手中的《汇编原理》。但是小红对小明说:“你先把《算法导论》给我了,我完成论文后就把《汇编原理》给你。” 小明不同意,他对小红说:“你把《汇编原理》先给我,我完成论文后把《算法导论》给你。” 这样,小红和小明各持有一本书,却又要求获得对方的书才交出自己持有的那本书。他们两人互不相让,结果就导致了死锁的发生。
现在我用JAVA语言对以上场景进行模拟:
- class Book
- {
- public String name;
- public float price;
- public Book(String name, float price)
- {
- this.name = name;
- this.price = price;
- }
- }
- class Student implements Runnable
- {
- private String studentName;
- private Book book1;
- private Book book2;
- public Student(String studentName,Book book1, Book book2)
- {
- this.book1 = book1;
- this.book2 = book2;
- this.studentName = studentName;
- }
- public void run()
- {
- synchronized(this.book1)
- {
- System.out.println(this.studentName+"拿到了"+this.book1.name +"开始写论文");
- Utilities.sleep(5000);
- System.out.println(this.studentName+"完成一半需要"+this.book2.name);
- synchronized(this.book2)
- {
- System.out.println(this.studentName+"拿到了"+this.book2.name +"继续写论文");
- }
- System.out.println(this.studentName+"完成了论文");
- }
- }
- }
- class Utilities
- {
- public static void sleep(int timeSpan)
- {
- try
- {
- Thread.sleep(timeSpan);
- }
- catch (Exception e)
- {
- System.out.println(e);
- }
- }
- }
- class Hello
- {
- public static void main(String[] args)
- {
- Book book1 = new Book("汇编原理",23.5f);
- Book book2 = new Book("算法导论",85.5f);
- Thread xh = new Thread(new Student("小红",book1,book2));
- Thread xm = new Thread(new Student("小明",book2,book1));
- xh.start();
- xm.start();
- }
- }
输出结果:
上图显示,程序一直卡在这个地方,不会往下执行。这就是死锁。
JAVA中关于同步与死锁的问题的更多相关文章
- Java多线程编程(同步、死锁、生产消费者问题)
Java多线程编程(同步.死锁.生产消费): 关于线程同步以及死锁问题: 线程同步概念:是指若干个线程对象并行进行资源的访问时实现的资源处理保护操作: 线程死锁概念:是指两个线程都在等待对方先完成,造 ...
- Java中线程同步的理解 - 其实应该叫做Java线程排队
Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可 ...
- java中线程同步的理解(非常通俗易懂)
转载至:https://blog.csdn.net/u012179540/article/details/40685207 Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运 ...
- 深入理解Java中的同步静态方法和synchronized(class)代码块的类锁
一.回顾学习内容 在前面几篇博客中我我们已经理解了synchronized对象锁.对象锁的重入.synchronized方法块.synchronized非本对象的代码块, 链接:https://www ...
- Java中线程同步的理解
我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可能和其他线程共享一些资源, ...
- 《java并发编程实战》读书笔记4--基础构建模块,java中的同步容器类&并发容器类&同步工具类,消费者模式
上一章说道委托是创建线程安全类的一个最有效策略,只需让现有的线程安全的类管理所有的状态即可.那么这章便说的是怎么利用java平台类库的并发基础构建模块呢? 5.1 同步容器类 包括Vector和Has ...
- Java中使用同步关键字synchronized需要注意的问题
在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行.synchronized既可以加在一段代码上,也可以加在 ...
- 菜鸡的Java笔记 - java 线程的同步与死锁 (同步 synchronization,死锁 deadlock)
线程的同步与死锁 (同步 synchronization,死锁 deadlock) 多线程的操作方法 1.线程同步的产生与解决 2.死锁的问题 ...
- java多线程(同步与死锁问题,生产者与消费者问题)
首先我们来看同步与死锁问题: 所谓死锁,就是A拥有banana.B拥有apple. A对B说:你把apple给我.我就把banana给你. B对A说:你把banana给我,我就把apple给你. 可是 ...
随机推荐
- hibernate反向工程 (eclipse和myeclipse)(转)
hibernate反向工程 (eclipse和myeclipse) 如何提取数据库的模式信息,想通过hibernate的反向工具尝试下. 一.myeclipse下hibernate反向工程: 1.选择 ...
- OpenJudge就算概论-最长单词2【寻找句子内部最长的单词】
/*===================================== 最长单词2 总时间限制: 1000ms 内存限制: 65536kB 描述 一个以'.'结尾的简单英文句子,单词之间用空格 ...
- Protocol Buffer Java实例
大家要先下载protobuffer,在这里: https://code.google.com/p/protobuf/downloads/list 注意,需要下载两个,一个是complier,另外一个是 ...
- Spark(一): 基本架构及原理
Apache Spark是一个围绕速度.易用性和复杂分析构建的大数据处理框架,最初在2009年由加州大学伯克利分校的AMPLab开发,并于2010年成为Apache的开源项目之一,与Hadoop和St ...
- dns 服务器配置
1.安装 named 2.配置如下文件: /etc/named.conf // 2 // named.conf 3 // 4 // Provided by Red Hat bind package t ...
- RDO部署openstack(2)
配置ML2和VXLAN 1. 安装和配置Neutron ML2 框架 (1) 安装在控制节点上(运行Neutron-server的节点) service neutron-server stop y ...
- Python(正则 Time datatime os sys random json pickle模块)
正则表达式: import re #导入模块名 p = re.compile(-]代表匹配0至9的任意一个数字, 所以这里的意思是对传进来的字符串进行匹配,如果这个字符串的开头第一个字符是数字,就代表 ...
- 【Java编程进阶-1】enum枚举的使用
枚举主要用于枚举常量,下面举个简单的应用. 比如一个公司有如下几个部门: 研发部: 销售部: 财务部: (其他部门暂时不列举) 部门的某些信息相对固定,此时可以考虑使用枚举来说明: 枚举类 Depts ...
- Redis桌面管理工具 RedisDesktopManager
下载链接地址:[官网地址:https://redisdesktop.com] redis-desktop-manager-0.8.8.384.exe Source code (zip) Source ...
- vmware在非正常关机后无法启动虚拟机
昨天使用vmware,由于笔记本温度过高,系统自动断电,导致实体机非正常关机.然后发现vmware无法启动虚拟机了,提示为‘This virtual machine appears to be in ...