synchronized和ReentrantLock实现消费者生产者问题
来源:互联网 发布:微分销系统源码开发 编辑:程序博客网 时间:2024/05/29 09:57
并发执行和并行执行的区别:并行执行是指两个或多个事件在同一时刻发生,而并发执行是指两个或多个事情在同一时间间隔内发生。并发执行在宏观层面上看,事情之间是同时发生的。比如说在2秒的时间内发生的两件事情,在历史的角度上可以看作是“同时发生”的。
在Java中,多个线程对临界区资源操作时,需要保持程序的可再现性,或者说内存可见性。不管哪个线程操作了临界资源,操作的结果都应该对下一个操作该资源的线程可见。我们需要通过线程间的同步机制来实现程序的可再现性。在Java中有两种方法实现:1.使用synchronized关键字 2.使用ReentrantLock对象
对于synchronized可以使用同步方法或者同步代码块的方式。使用这种方法,我们需要给定一个锁对象。
public class Resource2 {// count为临界资源private int count;//flag标记是否是应该生产还是消费private boolean flag = false;public int getCount() {return count;}public void setCount(int count) {this.count = count;}public void productor() {synchronized (this) {while (!flag) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}count++;System.out.println(Thread.currentThread().getName() + "。。。。。生产。。。。"+ count);flag = false;notifyAll();}}public void customer() {synchronized (this) {while (flag) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+ "。。。。。。。。。。。消费。。。。。。。。" + count);flag = true;notifyAll();}}}
这里使用了同步代码块,注意的是wait()方法和notifyAll()方法是锁调用的。因为锁的状态由系统在维护,所以锁被释放的时候,只有它自己知道。这里使用的是对象本身。当然啦,可以直接在方法上加synchronized,这里默认的锁仍然是对象本身,但是当方法是静态的时候则是对象的字节码对象,即 类名.Class。notify方法是从线程池中唤醒其中一个线程,notifyAll很明显是把所有的线程都唤醒。很明显这里要用notifyAll,如果使用notify则可能会出现死锁的状况。假如前一个wait的是生产者,而notify唤醒的签好也是生产者线程,那么生产的东西无法被消费,所以会一直等待....
我们来介绍第二种方式,对于ReentrantLock,你需要自己创建锁,上锁然后释放锁。这会在某些情况下带给我们很好的处理,我们可以自己进行出错时处理,而不像synchronized,由系统维护者,出错时只能由系统处理,一般是抛出异常或错误。而且ReentrantLock还提供了trylock(int timeout, Type),通过这个方法,你可以在线程无法获得锁的时候去执行其它的任务,而不是像synchronized那样,获取不到就会一直等待着。这个方法该怎么唤醒其它线程呢,是不是跟synchronized那样使用锁的wait()和notify()或者notifyAll()呢?当然不是啦。ReentrantLock只是提供了锁,而锁的释放或者上锁是的状态是要通过ReentrantLock的内部类Condition来监视的。说白了Condition就是锁的一个监视器,同一把锁可以定义多组监视器,这样在分工的时候就不需要唤醒所有的线程,而是唤醒所需职能的线程。对于生产者消费者我们可以定义两组监视器,分别监听这两种分工线程。当然啦,锁由你创建并操作,那么你操作完了应该释放它,不然会出大问题。为了保证锁的释放,肯定在finally中进行啦。
public class Resource{//count为临界资源private int count;private boolean flag = true;//锁private ReentrantLock lock;//两组监视器private Condition proCondition;private Condition cusCondition;public Resource(){lock = new ReentrantLock();proCondition = lock.newCondition();cusCondition = lock.newCondition();}public Resource(int count){this.count = count;lock = new ReentrantLock();proCondition = lock.newCondition();cusCondition = lock.newCondition();}public int getCount() {return count;}public void setCount(int count) {this.count = count;}public void productor(){lock.lock();try {while(!flag){try {proCondition.await();} catch (InterruptedException e) {e.printStackTrace();}}count++;System.out.println(Thread.currentThread().getName()+"。。。。。生产。。。。"+count);flag = false;cusCondition.signal();}finally{lock.unlock();}}public void customer(){lock.lock();try {while(flag){try {cusCondition.await();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+"。。。。。。。。。。。消费。。。。。。。。"+count);flag = true;proCondition.signal();}finally{lock.unlock();}}}
最后定义两个任务
public class MainActivity {public static void main(String[] args) {Resource2 resource2 = new Resource2();ResourceTask proTask = new ResourceTask(resource2);HandlerTask cusTask = new HandlerTask(resource2);Thread proThread1 = new Thread(proTask);Thread proThread2 = new Thread(proTask);Thread cusThread3 = new Thread(cusTask);Thread cusThread4 = new Thread(cusTask);proThread1.start();proThread2.start();cusThread3.start();cusThread4.start();}static class ResourceTask implements Runnable{private Resource2 resource;public ResourceTask(Resource2 resource){this.resource = resource;}@Overridepublic void run() {while(true)resource.productor();}}static class HandlerTask implements Runnable{private Resource2 resource;public HandlerTask(Resource2 resource){this.resource = resource;}@Overridepublic void run() {while(true)resource.customer();}}}
- synchronized和ReentrantLock实现消费者生产者问题
- synchronized 实现生产者消费者问题
- 使用ReentrantLock模拟简单生产者和消费者问题
- 使用ReentrantLock和Condition实现生产者消费者模型
- ReentrantLock方式实现生产者-消费者模式
- 使用ReentrantLock实现生产者消费者模式
- synchronized与Lock 的区别&分别实现生产者/消费者问题
- 用java实现生产者和消费者问题
- Java实现生产者和消费者问题
- Lock锁 实现生产者和消费者问题
- 用java实现生产者和消费者问题
- 生产者和消费者问题的Java实现
- 通过BlockingQueue实现生产者和消费者问题
- 生产者消费者问题(实现)
- 消费者和生产者问题
- 生产者和消费者问题
- 生产者和消费者问题
- 生产者和消费者问题
- JVM与GC
- weui实例:城市便民自行车查询
- Xcode中利用git源码版本控制
- DMA技术
- hiho一下第二周#1014 : Trie树
- synchronized和ReentrantLock实现消费者生产者问题
- 计算机视觉、机器学习相关领域论文和源代码大集合
- tomcat使用startup.bat启动闪退的解决办法
- Ehcache(06)——监听器
- IAR 的一个警告546
- 在单片机或者ARM程序中定义数据结构遇到的问题之一
- BZOJ2182: [Spoj1479]The GbAaY Kingdom最小直径生成树
- Java中的包装类
- [转]关于Sublime的repl设置