线程的同步与死锁

1,同步问题引出

  在多线程的处理之中,可以利用Runnable描述多个线程操作的资源,而Thread描述每一个线程对象,对于当多个线程访问统一资源的时候如果处理不当就会产生数据的错误操作。

  ①同步问题的引出

  下面编写一个买票程序,将创建若干个线程的对象实现卖票处理操作。

  ·范例:实现卖票操作

 class MyThread implements Runnable{
private int ticket=10;//总票数为10张
@Override
public void run() {
while (true){
if(this.ticket>0){
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"卖票,ticket="+this.ticket--);
}else {
System.out.println("****** 票已经卖光了 *********");
break;
}
}
}
}
public class Main {
public static void main(String[] args) {
MyThread myThread=new MyThread();
new Thread(myThread,"票贩子A").start();
new Thread(myThread,"票贩子B").start();
new Thread(myThread,"票贩子C").start();
new Thread(myThread,"票贩子D").start();
new Thread(myThread,"票贩子E").start();
}
}
 票贩子A卖票,ticket=0
****** 票已经卖光了 *********
票贩子B卖票,ticket=1
****** 票已经卖光了 *********
票贩子C卖票,ticket=-2
****** 票已经卖光了 *********
票贩子D卖票,ticket=-3
****** 票已经卖光了 *********
****** 票已经卖光了 *********

  此时的程序将创建三个线程对象,并且这三个线程对象将进行5章票的出售。此时的程序在进行卖票处理的时候并没有任何的问题(这是假象),下面可以模拟一下卖票过程中的延迟操作。

2,线程同步处理

  经过分析之后已经可以确定同步问题所产生的主要原因了,那么下面就需要进行进行同步问题的关键是锁,指的是当某一个线程执行操作的时候,其他线程外面等待;

  如果想要在程序之中实现这把锁的功能,就可以使用synchronized关键字来实现,利用此关键字可以定义同步方法或同步代码块,在同步代码块的操作里面的代码只允许一个线程执行。

  ①利用同步代码块进行处理:

 synchronized (同步操作){
同步代码操作;
}

  ·范例:利用同步代码块解决数据同步访问问题一般要进行同步对象处理的时候可以采用当前对象this进行同步。

 class MyThread implements Runnable{
private int ticket=10;//总票数为10张
@Override
public void run() {
while (true){
synchronized(this){//每一次只允许一个线程进行执行
if(this.ticket>0){
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"卖票,ticket="+this.ticket--);
}else {
System.out.println("* 票已经卖光了 *");
break;
}
}
}
}
}
public class Main {
public static void main(String[] args) {
MyThread myThread=new MyThread();
new Thread(myThread,"票贩子A").start();
new Thread(myThread,"票贩子B").start();
new Thread(myThread,"票贩子C").start();
}
}

  ②利用同步方法解决:只需要在方法定义上使用synchronized关键字即可加入同步处理之后,程序的整体的执行的性能下降了。同步实际上会造成性能的降低。

 class MyThread implements Runnable{
private int ticket=10;//总票数为10张
public synchronized boolean sale(){
if(this.ticket>0){
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"卖票,ticket="+this.ticket--);
return true;
}else {
System.out.println("****** 票已经卖光了 *********");
return false;
}
}
@Override
public void run() {
while (this.sale()){
;//空语句
}
}
}
public class Main {
public static void main(String[] args) {
MyThread myThread=new MyThread();
new Thread(myThread,"票贩子A").start();
new Thread(myThread,"票贩子B").start();
new Thread(myThread,"票贩子C").start();
}
}

  在日后学习Java类库的时候会发现,系统中使用的类上使用的许多同步处理采用的都是同步方法。

  注意:同步会造成性能的下降,并发才会高性能。

3,线程死锁

  死锁是在进行多线程同步的处理之中有可能产生的一种问题,所谓的死锁指的是若干个线程彼此互相等待的状态。

  ·范例:通过一个简单的代码观察死锁

 public class DeadLock implements Runnable{
private Jian jj =new Jian();
private XiaoQiang xq=new XiaoQiang(); @Override
public void run() {
jj.say(xq);
}
public DeadLock(){//构造方法
new Thread(this).start();
xq.say(jj);
}
public static void main(String[] args) {
new DeadLock();
}
} class Jian{
public synchronized void say(XiaoQiang xq){
System.out.println("阿建说:此路是我开留下买路财");
xq.get();
}
public synchronized void get(){
System.out.println("阿建说:获得过路费买饭吃");
}
}
class XiaoQiang{
public synchronized void say(Jian jj){
System.out.println("小强说:先过路在给钱");
jj.get();
}
public synchronized void get(){
System.out.println("小强说:通过道路去上班");
}
}

  若干线程访问同一资源时一定要进行同步处理,而过多的同步会造成死锁。现在死锁造成的主要原因是因为彼此都在互相等待着,等待着对方先让出资源。死锁是开发中的一种不确定的状态,有的时候代码处理不当则会不定期出现死锁,这是属于正常开发中的调试问题。

最新文章

  1. PHP unserialize()
  2. AutoLearnSkills.lua --升级自动学习技能
  3. 【FTP】FTP文件上传下载-支持断点续传
  4. DIV设置overflow无效的原因
  5. JS页面跳转 神器! window.href window.open
  6. org.springframework.beans.factory.BeanDefinitionStoreException
  7. flex基础学习
  8. Codeforces 374B - Inna and Nine
  9. tcpdump使用和TCP/IP包分析
  10. python+selenium+Eclipse安装
  11. 迭代器 Iterator
  12. Java课程设计 猜数游戏个人博客
  13. QT自定义控件插件化简要概述
  14. JAVA之旅(三十一)——JAVA的图形化界面,GUI布局,Frame,GUI事件监听机制,Action事件,鼠标事件
  15. ES2015也就是ES6知识点持续更新
  16. EffectiveC++ 第7章 模板与泛型编程
  17. Spock - Document -04- Interaction Based Testing
  18. PHP socket以及http、socket、tcp、udp
  19. error: Error retrieving parent for item: No resource found that matches the given name 'android:Widget.Material.ActionButton'.
  20. python--第五天总结

热门文章

  1. 单调队列优化dp(捡垃圾的机器人)
  2. Android跨进程通信广播(Broadcast)
  3. 如何向一个Fragment传递参数---setArguments方法的介绍
  4. Sublime text3中文版 无法安装插件There are no packages available for installation问题的解决。
  5. [Kerberos] Kerberos教程(一)
  6. 解决Hash碰撞冲突的方法
  7. 1. hadoop使用启动命令时报错之分析解决
  8. centos7.2 mysql tar.gz 搭建 (亲测成功)
  9. UE4 RHI(2)
  10. 利用ceph-deploy安装ceph