黑马程序员技术交流社区

标题: 已解决多线程的锁 [打印本页]

作者: 毛标    时间: 2012-8-18 09:53
标题: 已解决多线程的锁
本帖最后由 毛标 于 2012-8-18 20:01 编辑

在学习多线程中,在锁的使用问题上总是弄不清什么时候用什么样的锁最合适,希望能有个详细的解答最好带着实例解释

作者: 左建飞    时间: 2012-8-18 11:10
我觉得在使用synchronized代码块或函数中,只有一个锁的情况下,使用this锁就是最好的。
  1. <span style="font-size:12px;">public class InputOutputDemo2
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 Res1 r=new Res1();
  6.                 Thread t1=new Thread(new Input1(r));
  7.                 Thread t2=new Thread(new Output1(r));
  8.                 t1.start();
  9.                 t2.start();
  10.                
  11.         }
  12. }
  13. class Res1
  14. {
  15.         private String name;
  16.         private String sex;
  17.         private boolean flag=false;
  18.         public synchronized void set(String name,String sex)//set和out是同步的,只需要设置一个锁,那么用this就可以了。
  19.         {
  20.                 if(flag)
  21.                         try{this.wait();}catch(InterruptedException e){}
  22.                 this.name=name;
  23.                 this.sex=sex;
  24.                 flag=true;
  25.                 this.notify();
  26.         }
  27.         public synchronized void out()
  28.         {
  29.                 if(!flag)
  30.                         try{this.wait();}catch(InterruptedException e){}
  31.                 System.out.println(name+"-----"+sex);
  32.                 flag=false;
  33.                 this.notify();
  34.         }
  35. }
  36. class Input1 implements Runnable
  37. {
  38.         private Res1 r;
  39.         Input1(Res1 r)
  40.         {
  41.                 this.r=r;
  42.         }
  43.         public void run()
  44.         {
  45.                 int x=0;
  46.                 while(true)
  47.                 {
  48.                         if(x==0)
  49.                                 r.set("zhangsan","man");
  50.                         else
  51.                                 r.set("lisi","woman");
  52.                         x=(x+1)%2;
  53.                 }
  54.         }
  55. }
  56. class Output1 implements Runnable
  57. {
  58.         private Res1 r;
  59.         Output1(Res1 r)
  60.         {
  61.                 this.r=r;
  62.         }
  63.         public void run()
  64.         {
  65.                 while(true)
  66.                 {
  67.                         r.out();
  68.                 }
  69.         }
  70. }
  71. </span>
复制代码
但是有两个以上的锁时,我们就需要另外建立对象,将其做为锁了。
  1. public class DeadThreadDemo {
  2.         public static void main(String[] args) {
  3.                 // TODO Auto-generated method stub
  4.                 Thread t1=new Thread(new Test(true));
  5.                 Thread t2=new Thread(new Test(false));
  6.                 t1.start();
  7.                 t2.start();
  8.         }

  9. }
  10. class Test implements Runnable
  11. {
  12.         private boolean flag;
  13.         Test(boolean flag)
  14.         {
  15.                 this.flag=flag;
  16.         }
  17.         public void run()
  18.         {
  19.                 if (flag)
  20.                 {
  21.                         while (true)
  22.                         {
  23.                                 synchronized(MyLock.locka)//     1    1与2两个代码块不是同步的,我们就需要建立两个对象,成为两个不同的锁。
  24.                                 {
  25.                                         System.out.println("if locka");
  26.                                         synchronized(MyLock.lockb)
  27.                                         {
  28.                                                 System.out.println("if lockb");
  29.                                         }
  30.                                 }
  31.                         }
  32.                 }
  33.                 else
  34.                 {
  35.                         while(true)
  36.                         {
  37.                                 synchronized(MyLock.lockb)//    2
  38.                                 {
  39.                                         System.out.println("else lockb");
  40.                                         synchronized(MyLock.locka)
  41.                                         {
  42.                                                 System.out.println("else locka");
  43.                                         }
  44.                                 }
  45.                         }
  46.                 }
  47.         }
  48. }
  49. class MyLock
  50. {
  51.         static Object locka=new Object();
  52.         static Object lockb=new Object();
  53. }
复制代码
在线程间通讯的情况下,使用Lock更为方便更有针对性。
  1. package day12;

  2. import java.util.concurrent.locks.Condition;
  3. import java.util.concurrent.locks.Lock;
  4. import java.util.concurrent.locks.ReentrantLock;

  5. public class ProducerCustomerDemo2
  6. {
  7.                 public static void main(String[] args)
  8.                 {
  9.                         Resource1 r=new Resource1();
  10.                         Producer1 p=new Producer1(r);
  11.                         Customer1 c=new Customer1(r);
  12.                         Thread t1=new Thread(p);
  13.                         Thread t2=new Thread(p);
  14.                         Thread t3=new Thread(c);
  15.                         Thread t4=new Thread(c);
  16.                         t1.start();
  17.                         t2.start();
  18.                         t3.start();
  19.                         t4.start();
  20.                 }
  21. }
  22. class Resource1
  23. {
  24.         private String name;
  25.         private int count;
  26.         private boolean flag=false;
  27.         private Lock lock=new ReentrantLock();//1.5版本新特性。相当与synchronized语句。
  28.         //private Condition condition=lock.newCondition();//Condition相当与监视器方法,由lock的newCondition()方法获取。
  29.         private Condition condition_pro=lock.newCondition();//每个lock可以建立多个condition,它们可以互相等待唤醒。
  30.         private Condition condition_cus=lock.newCondition();
  31.         public void set(String name)throws InterruptedException
  32.         {
  33.                 lock.lock();//上锁
  34.                 try
  35.                 {
  36.                         while(flag)
  37.                                 condition_pro.await();//由await()替换wait()方法
  38.                         this.name=name+"----"+count++;
  39.                         System.out.println(Thread.currentThread().getName()+"...生产者。。。"+this.name);
  40.                         flag=true;
  41.                         condition_cus.signal();//由signal()替换notify(),由signalAll()替换notifyAll()
  42.                 }
  43.                 finally
  44.                 {
  45.                         lock.unlock();
  46.                 }
  47.         }
  48.         public void out()throws InterruptedException
  49.         {
  50.                 lock.lock();
  51.                 try
  52.                 {
  53.                         while(!flag)
  54.                                 condition_cus.await();
  55.                         System.out.println(Thread.currentThread().getName()+"...消费者。。。。。。。。"+this.name);
  56.                         flag=false;
  57.                         condition_pro.signal();
  58.                 }
  59.                 finally
  60.                 {
  61.                         lock.unlock();
  62.                 }
  63.         }
  64. }
  65. class Producer1 implements Runnable
  66. {
  67.         private Resource1 r;
  68.         Producer1(Resource1 r)
  69.         {
  70.                 this.r=r;
  71.         }
  72.         public void run()
  73.         {
  74.                 while(true)
  75.                 {
  76.                         try
  77.                         {
  78.                                 r.set("商品");
  79.                         }
  80.                         catch(InterruptedException e){}
  81.                 }
  82.         }
  83. }
  84. class Customer1 implements Runnable
  85. {
  86.         private Resource1 r;
  87.         Customer1(Resource1 r)
  88.         {
  89.                 this.r=r;
  90.         }
  91.         public void run()
  92.         {
  93.                 while(true)
  94.                 {
  95.                         try
  96.                         {
  97.                                 r.out();
  98.                         }
  99.                         catch(InterruptedException e){}
  100.                 }
  101.         }
  102. }
复制代码





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2