线程同步死锁
Posted bfcs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程同步死锁相关的知识,希望对你有一定的参考价值。
1.线程同步(即上锁,同步锁)实现的方式
1)同步代码块
synchronized(obj){ //obj称为同步监视器,obj要监视的对象
}
同步监视器只能是对象,推荐使用共享资源的对象,可以当前对象 this,也可以是其它的对象
1 public class Ticket1 implements Runnable{ 2 private int ticket=5; 3 @Override 4 public void run() { 5 for(int i=0;i<100;i++){ //每个窗口排了100个人 6 synchronized (this) { //同步代码块 7 if(ticket>0){//有票 8 try { 9 Thread.sleep(300); 10 } catch (InterruptedException e) { 11 // TODO Auto-generated catch block 12 e.printStackTrace(); 13 } 14 System.out.println(Thread.currentThread().getName()+"正在卖第"+(ticket--)+"张票"); 15 } 16 } 17 } 18 } 19 }
1 public class TestTicket1 { 2 public static void main(String[] args) { 3 Ticket1 ticket=new Ticket1(); 4 //创建Thread类 5 Thread t1=new Thread(ticket, "A窗口"); 6 Thread t2=new Thread(ticket,"B窗口"); 7 Thread t3=new Thread(ticket,"C窗口"); 8 //启动线程 9 t1.start(); 10 t2.start(); 11 t3.start(); 12 } 13 }
2)同步方法
同步方法的同步监视器为当前对象this
public synchronized void 方法名(参数列表){
}
1 public class Ticket2 implements Runnable{ 2 private int ticket=5; 3 @Override 4 public void run() { 5 for(int i=0;i<100;i++){ //每个窗口排了100个人 6 //调用同步方法 7 this.saleTicket(); 8 } 9 } 10 private synchronized void saleTicket(){ //无需指定同步监视器,同步监视器只能是当前对象this 11 if(ticket>0){//有票 12 try { 13 Thread.sleep(300); 14 } catch (InterruptedException e) { 15 // TODO Auto-generated catch block 16 e.printStackTrace(); 17 } 18 System.out.println(Thread.currentThread().getName()+"正在卖第"+(ticket--)+"张票"); 19 } 20 } 21 }
1 public class TestTicket2 { 2 public static void main(String[] args) { 3 Ticket2 ticket=new Ticket2(); 4 //创建Thread类 5 Thread t1=new Thread(ticket, "A窗口"); 6 Thread t2=new Thread(ticket,"B窗口"); 7 Thread t3=new Thread(ticket,"C窗口"); 8 //启动线程 9 t1.start(); 10 t2.start(); 11 t3.start(); 12 } 13 }
2.死锁及解决
产生原因:多线程操作时,互相等待对方的资源
1 public class DeadLock extends Thread { 2 private Object money;//钱 3 private Object water;//水 4 public boolean flag;//标识持有对象锁 5 6 public DeadLock(Object money, Object water) { 7 super(); 8 this.money = money; 9 this.water = water; 10 } 11 12 @Override 13 public void run() { 14 if(flag){//true时,持有“钱”的锁 15 synchronized (money) { 16 System.out.println("有钱,等水"); 17 try { 18 Thread.sleep(300); 19 } catch (InterruptedException e) { 20 // TODO Auto-generated catch block 21 e.printStackTrace(); 22 } 23 synchronized (water) { 24 System.out.println("有水,等钱"); 25 } 26 } 27 }else{ 28 synchronized (water) { 29 System.out.println("有水,等钱"); 30 try { 31 Thread.sleep(300); 32 } catch (InterruptedException e) { 33 // TODO Auto-generated catch block 34 e.printStackTrace(); 35 } 36 synchronized (money) { 37 System.out.println("有钱,等水"); 38 } 39 } 40 41 } 42 } 43 }
1 public class Test { 2 public static void main(String[] args) { 3 //创建共享资源的对象 4 Object money=new Object(); 5 Object water=new Object(); 6 //创建线程类的对象 7 DeadLock d1=new DeadLock(money, water); 8 DeadLock d2=new DeadLock(money, water); 9 d1.flag=true; 10 d2.flag=false; 11 //启动线程 12 d1.start(); 13 d2.start(); 14 } 15 }
无法完成一个循环
如何解决死锁:不要让两个对象同时持有对象锁,采用互斥方式来解决
把 synchronized嵌套改为同级并列
1 public class DeadLock2 extends Thread { 2 private Object money;//钱 3 private Object water;//水 4 public boolean flag;//标识持有对象锁 5 6 public DeadLock2(Object money, Object water) { 7 super(); 8 this.money = money; 9 this.water = water; 10 } 11 12 @Override 13 public void run() { 14 if(flag){//true时,持有“钱”的锁 15 synchronized (money) { 16 System.out.println("有钱,等水"); 17 try { 18 Thread.sleep(300); 19 } catch (InterruptedException e) { 20 // TODO Auto-generated catch block 21 e.printStackTrace(); 22 } 23 24 } 25 synchronized (water) { 26 System.out.println("有水,等钱"); 27 } 28 }else{ 29 synchronized (water) { 30 System.out.println("有水,等钱"); 31 try { 32 Thread.sleep(300); 33 } catch (InterruptedException e) { 34 // TODO Auto-generated catch block 35 e.printStackTrace(); 36 } 37 38 } 39 synchronized (money) { 40 System.out.println("有钱,等水"); 41 } 42 43 } 44 }
1 public class Test2 { 2 public static void main(String[] args) { 3 //创建共享资源的对象 4 Object money=new Object(); 5 Object water=new Object(); 6 //创建线程类的对象 7 DeadLock2 d1=new DeadLock2(money, water); 8 DeadLock2 d2=new DeadLock2(money, water); 9 d1.flag=true; 10 d2.flag=false; 11 //启动线程 12 d1.start(); 13 d2.start(); 14 } 15 }
死锁的避免
银行家算法:该算法需要检查申请者对资源的最大需求量,如果系统现存的各类资源可以满足申请者的请求,就满足申请者的请求。这样申请者就可很快完成其计算,然后释放它
占用的资源,从而保证了系统中的所有进程都能完成,所以可避免死锁的发生。(计算资源的大小,计算出来后,永远按照从大到小的方式来获得锁)
以上是关于线程同步死锁的主要内容,如果未能解决你的问题,请参考以下文章