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中关于同步与死锁的问题的更多相关文章

  1. Java多线程编程(同步、死锁、生产消费者问题)

    Java多线程编程(同步.死锁.生产消费): 关于线程同步以及死锁问题: 线程同步概念:是指若干个线程对象并行进行资源的访问时实现的资源处理保护操作: 线程死锁概念:是指两个线程都在等待对方先完成,造 ...

  2. Java中线程同步的理解 - 其实应该叫做Java线程排队

    Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可 ...

  3. java中线程同步的理解(非常通俗易懂)

    转载至:https://blog.csdn.net/u012179540/article/details/40685207 Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运 ...

  4. 深入理解Java中的同步静态方法和synchronized(class)代码块的类锁

    一.回顾学习内容 在前面几篇博客中我我们已经理解了synchronized对象锁.对象锁的重入.synchronized方法块.synchronized非本对象的代码块, 链接:https://www ...

  5. Java中线程同步的理解

    我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可能和其他线程共享一些资源, ...

  6. 《java并发编程实战》读书笔记4--基础构建模块,java中的同步容器类&并发容器类&同步工具类,消费者模式

    上一章说道委托是创建线程安全类的一个最有效策略,只需让现有的线程安全的类管理所有的状态即可.那么这章便说的是怎么利用java平台类库的并发基础构建模块呢? 5.1 同步容器类 包括Vector和Has ...

  7. Java中使用同步关键字synchronized需要注意的问题

    在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行.synchronized既可以加在一段代码上,也可以加在 ...

  8. 菜鸡的Java笔记 - java 线程的同步与死锁 (同步 synchronization,死锁 deadlock)

    线程的同步与死锁 (同步 synchronization,死锁 deadlock)        多线程的操作方法            1.线程同步的产生与解决        2.死锁的问题     ...

  9. java多线程(同步与死锁问题,生产者与消费者问题)

    首先我们来看同步与死锁问题: 所谓死锁,就是A拥有banana.B拥有apple. A对B说:你把apple给我.我就把banana给你. B对A说:你把banana给我,我就把apple给你. 可是 ...

随机推荐

  1. linux服务之openldap

    http://www.openldap.org/ http://blog.csdn.net/chinalinuxzend/article/details/1870656 OpenLDAP学习笔记 ht ...

  2. event.srcElement兼容处理

    在IE下,event对象有srcElement属性,但是没有target属性:Firefox下,even对象有target属性,但是没有srcElement属性.. 解决方法:使用obj(obj = ...

  3. EDM营销算法:python自动批量发邮件

    EDM营销:全称Email Direct Marketing,即电子邮件营销.企业可以通过使用EDM软件向目标客户发送EDM邮件,建立同目标顾客的沟通渠道,向其直接传达相关信息,用来促进销售.EDM软 ...

  4. Andaroid L新特性

    1.Material Design”(材料设计)的全新设计理念,和Holo相比,Material Design更加色彩丰富,不像Holo那样灰暗 2.1)卡片风格(锁屏界面) 2)环动式设计  And ...

  5. openstack(liberty):部署实验平台(三,简单版本软件安装 之cinder,swift)

    今天这里追加存储相关的部署,主要是Block和Object,为了看到效果,简单的部署在单节点上,即Block一个节点,Object对应一个节点. 读者可能会觉得我这个图和之前的两个post有点点不同, ...

  6. Ext JS4 学习笔记之发送表单(Form)时也将表单下的表格(Grid)数据一同发送的方法

    Ext JS4 学习笔记之发送表单(Form)时也将表单下的表格(Grid)数据一同发送的方法 昨天在开发的时候遇到个小问题,就是如何将Grid的内容与Form一起发送到服务器端.默认情况下,表单(F ...

  7. runliuv, 安卓查看WIFI密码

    用RE查看data/misc/wifi/wpa_supplicant.conf或者其他文件名以.conf结尾的文件

  8. MySQL压缩包安装

    1.解压缩 2.添加环境变量 3.添加配置文件 my.ini 4.以管理员身份初始化数据库 mysqld --initialize --user=mysql --console 5.以管理员身份将My ...

  9. 解决 SQLite数据库 no current row

    场景: SQLite数据库,在查询数据时,提示 标题错误异常.查看堆栈,是在SQLiteDataReader.CheckValidRow 时报错. 数据查询是通过 adapter.Fill(dt) 进 ...

  10. PHP之单例模式的实现

    单例模式: 单例模式又称职责模式:简单的说,一个对象(在学习设计模式之前,需要比较了解面向对象思想)只负责一个特定的任务: 单例类: 1.构造函数需要标记为private(访问控制:防止外部代码使用n ...