两种实现线程同步的方法

方法 特性
synchronized  不需要显式的加锁,易实现
ReentrantLock 需要显式地加解锁,灵活性更好,性能更优秀,结合Condition可实现多种条件锁 
package com.concurrent.test;

import java.util.Stack;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock; /**
* @Description: 三种方法实现生产者/消费者
*/
public class ThreadSynchronizeTest { public static void main(String[] args) {
ProducerConsumer producerConsumer = new ProducerConsumerViaBlockingQueue();
producerConsumer.test();
}
} abstract class ProducerConsumer {
protected int capacity = 10;
protected int element = 0; protected abstract void produce() throws InterruptedException; protected abstract void consume() throws InterruptedException; public void test() {
Thread producer = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}); Thread consumer = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
}); producer.start();
consumer.start(); }
} /**
* 方法一:ReentrantLock结合Condition
*/
class ProducerConsumerViaReentrantLock extends ProducerConsumer {
private Stack<Integer> stack = new Stack<>();
private ReentrantLock lock = new ReentrantLock();
private Condition notFull = lock.newCondition();
private Condition notEmpty = lock.newCondition(); @Override
protected void produce() throws InterruptedException {
try {
lock.lock();
if (stack.size() == capacity) {
notFull.await();
} ++element;
System.out.println(Thread.currentThread().getId() + "," + Thread.currentThread().getName() + " produce " + element);
stack.push(element);
notEmpty.signalAll();
Thread.sleep(1000L);
} finally {
lock.unlock();
}
} @Override
protected void consume() throws InterruptedException {
try {
lock.lock();
if (stack.isEmpty()) {
notEmpty.await();
}
int element = stack.pop();
System.out.println(Thread.currentThread().getId() + "," + Thread.currentThread().getName() + " consume " + element);
notFull.signalAll();
} finally {
lock.unlock();
}
} } /**
* 方法二:synchronized 结合 wait、notify、notifyAll
*/
class ProducerConsumerViaObjectLock extends ProducerConsumer { private Stack<Integer> stack = new Stack<>();
private Object lock = new Object(); @Override
protected void produce() throws InterruptedException {
/*
* 1,lock为监视器
* 2,wait/notify/notifyAll方法必须在synchronized块内调用
* 3,调用wait/notify/notifyAll方法但不持有监视器的使用权将会抛出java.lang.IllegalMonitorStateException
*/
synchronized (lock) {
if (stack.size() == capacity) {
lock.wait();
} ++element;
System.out.println(Thread.currentThread().getId() + "," + Thread.currentThread().getName() + " produce " + element);
stack.push(element);
lock.notifyAll();
Thread.sleep(1000L);
}
} @Override
protected void consume() throws InterruptedException {
synchronized (lock) {
if (stack.isEmpty()) {
lock.wait();
} int element = stack.pop();
System.out.println(Thread.currentThread().getId() + "," + Thread.currentThread().getName() + " consume " + element);
lock.notifyAll();
}
}
} /**
* 方法三:BlockingQueue
*/
class ProducerConsumerViaBlockingQueue extends ProducerConsumer { private BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(capacity); @Override
protected void produce() throws InterruptedException {
++element;
System.out.println(Thread.currentThread().getId() + "," + Thread.currentThread().getName() + " produce " + element);
queue.put(element);
Thread.sleep(1000L);
} @Override
protected void consume() throws InterruptedException {
int element = queue.take();
System.out.println(Thread.currentThread().getId() + " consume " + element);
Thread.sleep(10000L);
}
}

最新文章

  1. Centos 下编译安装Redis
  2. Web 播放声音 — AMR(Audio) 篇
  3. Git-仓库迁移
  4. Ubuntu环境下手动配置ant
  5. 详解struts.multipart.saveDir的临时文件路径
  6. Xcode7 网络请求报错
  7. Android为应用在桌面添加一个快捷方式
  8. COGS 渡轮问题 (LIS规定字典序输出方案数)
  9. ios 中的UI控件学习总结(1)
  10. qt5_qml_Opengl_shader 第一弹----------------------openglunderqml的简化及介绍
  11. Intel baytrail-t support Linux?
  12. Unity 使用TexturePackerGUI打包图集 Sprite 图片边上有线
  13. [js高手之路]面向对象+设计模式+继承一步步改造简单的四则运算
  14. 在Windows上运行Linux
  15. python网络编程基础
  16. 将泛类型集合List类转换成DataTable
  17. ansible中的map
  18. 关于苹果手机微信端 position: fixed定位top导航栏问题
  19. National Property CodeForces - 875C (拓扑排序)
  20. 【微信JSSDK】PHP版微信录音文件下载

热门文章

  1. [STemWin教程入门篇]第二期:emWin5.xx的详细移植步骤
  2. javascript函数调用的几种方式
  3. Rust &lt;3&gt;:控制流
  4. HBase优化——读写优化
  5. document.readyState和document.DOMContentLoaded判断DOM的加载完成
  6. 破解Pycharm 2019.2
  7. 看过这些我明白了依赖注入及IoC
  8. 微信小程序の小程序事件流
  9. ScrollView嵌套listview显示一行bug
  10. 2018-8-10-win10-uwp-dataGrid