A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黑马-zhangping 中级黑马   /  2012-10-20 00:15  /  1173 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

如何实现线程同步,有哪几种方法,最好附上代码,帮助理解,谢谢

评分

参与人数 1黑马币 +10 收起 理由
刘芮铭 + 10

查看全部评分

3 个回复

倒序浏览
问的好宽泛啊,建议看书看视频更加清晰吧
1 用同步代码块可以解决这个问题,格式为:
synchronized(对象)
{
    需要被同步的代码;
}

同步的好处:解决了线程的安全问题;
同步的弊端:相对降低了效率,因为同步外的线程都会判断同步锁。
同步的前提:同步中必须有多个线程,并使用同一个锁。
  1. class Resource  
  2. {  
  3.     private String name;  
  4.     private int count=1;  
  5.     private boolean flag=false;  
  6.     public synchronized void set(String name)  
  7.     {  
  8.         while(flag)  
  9.             try{wait();}catch(InterruptedException e){}  
  10.         this.name=name+count;  
  11.         count++;  
  12.         System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);  
  13.         flag=true;  
  14.         notifyAll();  
  15.     }  
  16.     public synchronized void get()  
  17.     {  
  18.         while(!flag)  
  19.         try{wait();}catch(InterruptedException e){}  
  20.         System.out.println(Thread.currentThread().getName()+"...消费者......"+this.name);  
  21.         flag=false;  
  22.         notifyAll();  
  23.     }  
  24. }  
  25.   
  26. class Producer implements Runnable  
  27. {  
  28.     private Resource r;  
  29.     Producer(Resource r)  
  30.     {  
  31.         this.r=r;  
  32.     }  
  33.     public void run()  
  34.     {  
  35.         while (true)  
  36.         {  
  37.             r.set("烤鸭");  
  38.         }  
  39.     }  
  40. }  
  41. class Consumer implements Runnable  
  42. {  
  43.     private Resource r;  
  44.     Consumer(Resource r)  
  45.     {  
  46.         this.r=r;  
  47.     }  
  48.     public void run()  
  49.     {  
  50.         while (true)  
  51.         {  
  52.             r.get();  
  53.         }  
  54.     }  
  55. }  
  56.   
  57. class  ProducerConsumerDemo  
  58. {  
  59.     public static void main(String[] args)   
  60.     {  
  61.         Resource r=new Resource();  
  62.         Producer pro=new Producer(r);  
  63.         Consumer con=new Consumer(r);  
  64.         Thread t0=new Thread(pro);  
  65.         Thread t1=new Thread(con);  
  66.         Thread t2=new Thread(pro);  
  67.         Thread t3=new Thread(con);  
  68.         t0.start();  
  69.         t1.start();  
  70.         t2.start();  
  71.         t3.start();  
  72.     }  
  73. }  
复制代码
接口 Lock
同步代码块,对于锁的操作时隐式的
jdk1.5以后,将同步和锁封装成了对象,并将操作锁的方式定义到了该对象中,将隐式动作变成了显式动作。
Lock lock=new ReentrantLock();
lock.lock();//获取锁
code...;//throw Exception();
lock.unlock();//释放锁
try
{
    lock.lock();//获取锁
}
finally
{
    lock.unlock;//释放锁
}

Lock接口:它的出现替代了同步代码块或者同步函数。将同步的隐式锁操作变成了显式锁操作;
同时更为灵活,可以一个锁上加上多组监视器。
    lock();获取锁
    unlock();释放锁,通常需要定义到finally代码块中。

Condition接口:它的出现替代了Object中的wait、notify、notifyAll方法。
                将这些监视器方法单独进行了封装,变成了Condition监视器对象,
                可以和任意锁组合。
    await();//等待
    signal();//唤醒一个等待线程
    signalAll();//唤醒所有等待线程
  1. import java.util.concurrent.locks.*;  
  2. class Resource  
  3. {  
  4.     private String name;  
  5.     private int count=1;  
  6.     private boolean flag=false;  
  7.     //创建一个锁对象  
  8.     Lock lock=new ReentrantLock();  
  9.     //通过已有的锁,获取该锁上的监视器对象  
  10.     //Condition con=lock.newCondition();  
  11.     //通过已有的锁,获取两组监视器;一组监视生产者,一组监视消费者  
  12.     Condition producer_con=lock.newCondition();  
  13.     Condition consumer_con=lock.newCondition();  
  14.     public void set(String name)  
  15.     {  
  16.         lock.lock();  
  17.         try  
  18.         {  
  19.             while(flag)  
  20.             try{producer_con.await();}catch(InterruptedException e){}  
  21.             this.name=name+count;  
  22.             count++;  
  23.             System.out.println(Thread.currentThread().getName()+"...生产者5.0..."+this.name);  
  24.             flag=true;  
  25.             consumer_con.signal();  
  26.         }  
  27.         finally  
  28.         {  
  29.             lock.unlock();  
  30.         }  
  31.   
  32.     }  
  33.     public void get()  
  34.     {  
  35.         lock.lock();  
  36.         try  
  37.         {  
  38.             while(!flag)  
  39.             try{consumer_con.await();}catch(InterruptedException e){}  
  40.             System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);  
  41.             flag=false;  
  42.             producer_con.signal();  
  43.         }  
  44.         finally  
  45.         {  
  46.             lock.unlock();  
  47.         }  
  48.          
  49.     }  
  50. }  
  51.   
  52. class Producer implements Runnable  
  53. {  
  54.     private Resource r;  
  55.     Producer(Resource r)  
  56.     {  
  57.         this.r=r;  
  58.     }  
  59.     public void run()  
  60.     {  
  61.         while (true)  
  62.         {  
  63.             r.set("烤鸭");  
  64.         }  
  65.     }  
  66. }  
  67. class Consumer implements Runnable  
  68. {  
  69.     private Resource r;  
  70.     Consumer(Resource r)  
  71.     {  
  72.         this.r=r;  
  73.     }  
  74.     public void run()  
  75.     {  
  76.         while (true)  
  77.         {  
  78.             r.get();  
  79.         }  
  80.     }  
  81. }  
  82.   
  83. class  ProducerConsumerDemo  
  84. {  
  85.     public static void main(String[] args)   
  86.     {  
  87.         Resource r=new Resource();  
  88.         Producer pro=new Producer(r);  
  89.         Consumer con=new Consumer(r);  
  90.         Thread t0=new Thread(pro);  
  91.         Thread t1=new Thread(con);  
  92.         Thread t2=new Thread(pro);  
  93.         Thread t3=new Thread(con);  
  94.         t0.start();  
  95.         t1.start();  
  96.         t2.start();  
  97.         t3.start();  
  98.     }  
  99. }  
复制代码

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1

查看全部评分

回复 使用道具 举报
目前我只知道  同步方法 和 同步代码块   并保证使用对象唯一,这样才可以实现同步。
回复 使用道具 举报
学习了!!!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马