黑马程序员—JAVA线程间通讯问题

------------- android培训java培训、期待与您交流! -------------

死锁现象:

示例:

class Test implements Runnable 
{ 
         private boolean flag; 
         Test(boolean flag) 
         { 
                 this.flag = flag; 
         }   
         public void run() 
         { 
                 if(flag) 
                 { 
                          while(true) 
                          { 
                                   synchronized(MyLock.locka) 
                                   { 
                                            System.out.println(Thread.currentThread().getName()+"...if locka "); 
                                            synchronized(MyLock.lockb) 
                                            { 
                                                     System.out.println(Thread.currentThread().getName()+"..if lockb");                                 
                                            } 
                                   } 
                          } 
                 } 
                 else 
                 { 
                          while(true) 
                          { 
                                   synchronized(MyLock.lockb) 
                                   { 
                                            System.out.println(Thread.currentThread().getName()+"..else lockb"); 
                                            synchronized(MyLock.locka) 
                                            { 
                                                     System.out.println(Thread.currentThread().getName()+".....else locka"); 
                                            } 
                                   } 
                          } 
                 } 
         } 
} 
class MyLock 
{ 
         static Object locka = new Object(); 
         static Object lockb = new Object(); 
}   
class  DeadLockTest 
{ 
         public static void main(String[] args)  
         { 
                 Thread t1 = new Thread(new Test(true)); 
                 Thread t2 = new Thread(new Test(false)); 
                 t1.start(); 
                 t2.start(); 
         } 
} 
原因分析: 
同步中嵌套同步,而两个同步用的不是同一个锁对象,会出现死锁情况。 

线程间的通讯:

其实就是多个线程在操作同一个资源,但是操作的动作不同。 

以生产者和消费者的代码例子总结:   

class ProducerConsumerDemo  
{ 
         public static void main(String[] args)  
         { 
                 Resource r = new Resource();   
                 Producer pro = new Producer(r); 
                 Consumer con = new Consumer(r); 
                 //创建四个线程 
                 Thread t1 = new Thread(pro); 
                 Thread t2 = new Thread(pro); 
                 Thread t3 = new Thread(con); 
                 Thread t4 = new Thread(con);   
                 t1.start(); 
                 t2.start(); 
                 t3.start(); 
                 t4.start();   
         } 
}   
class Resource 
{ 
         private String name; 
         private int count = 1; 
         private boolean flag = false; 
         public synchronized void set(String name) 
         { 
                 while(flag)//当使用if时会出现生产一个消费多个或者生产多个消费一个的情况 
                          try{this.wait();}catch(Exception e){}                         
this.name = name+"--"+count++; 
         System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name); 
                 flag = true; 
                 this.notifyAll();//如果用notify()方法会出现全部等待的情况 
         }   
         public synchronized void out() 
         { 
                 while(!flag) 
                          try{wait();}catch(Exception e){}         
	        System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name); 
                 flag = false; 
                 this.notifyAll(); 
         } 
}   
class Producer implements Runnable 
{ 
         private Resource res;   
         Producer(Resource res) 
         { 
                 this.res = res; 
         } 
         public void run() 
         { 
                 while(true) 
                 { 
                          res.set("+商品+"); 
                 } 
         } 
}   
class Consumer implements Runnable 
{ 
         private Resource res; 
  
         Consumer(Resource res) 
         { 
                 this.res = res; 
         } 
         public void run() 
         { 
                 while(true) 
                 { 
                          res.out(); 
                 } 
         } 
} 
总结: 
对于多个生产者和消费者。为什么要定义while判断标记。 
原因:让被唤醒的线程再一次判断标记。 
为什么定义notifyAll, 
因为需要唤醒对方线程。因为只用notify,容易出现只唤醒本方线程的情况。导致程序中的所有线程都等待。 
JDK1.5 中提供了多线程升级解决方案
将同步Synchronized替换成现实Lock操作。 
将Object中的wait,notify notifyAll,替换了Condition对象。 
该对象可以Lock锁 进行获取。 
该示例中,实现了本方只唤醒对方操作。 
  
Lock:替代了Synchronized 
         lock  
         unlock 
         newCondition() 
  
Condition:替代了Object wait notify notifyAll 
         await(); 
         signal(); 
         signalAll(); 

代码示例:

  
class Resource 
{ 
         private String name; 
         private int count = 1; 
         private boolean flag = false; 
         private Lock lock = new ReentrantLock(); 
         private Condition condition_pro = lock.newCondition(); 
         private Condition condition_con = lock.newCondition(); 
         public  void set(String name)throws InterruptedException 
         { 
                 lock.lock(); 
                 try 
                 { 
                          while(flag) 
                                   condition_pro.await();//t1,t2 
                          this.name = name+"--"+count++; 
  
                          System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name); 
                          flag = true; 
                          condition_con.signal(); 
                 } 
                 finally 
                 { 
                          lock.unlock();//释放锁的动作一定要执行。 
                 } 
         }     
         public  void out()throws InterruptedException 
         { 
                 lock.lock(); 
                 try 
                 { 
                          while(!flag) 
                                   condition_con.await(); 
                          System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name); 
                          flag = false; 
                          condition_pro.signal(); 
                 } 
                 finally 
                 { 
                          lock.unlock(); 
                 }                   
         } 
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值