Java 5以前的线程同步采用syncronized和wait,notify,notifyAll来实现,比较粗糙。之后有了Lock和Condition。
ReentrantLock的简单lock,unlock相当于syncronized。而通过condition的signal和await,可以实现更细粒度的控制。

http://www.cnblogs.com/yaowukonga/archive/2012/08/27/2658329.html  http://blog.csdn.net/vernonzheng/article/details/8288251 http://blog.csdn.net/fw0124/article/details/6672522

下面这个例子是本人的实现,望指正。基本意思是H函数会产生H分子,O函数产生O分子,每个线程产生一个分子,当有两个H一个O时,这三个线程退出。

实现思路是用Condition的Queue来存顺序,这样能够控制线程退出的顺序(也能够根据需求实现不同的顺序),而且能避免惊群。测试用例简单测试了当H和O不足和超出时的情形。

import java.util.*;
import java.util.concurrent.locks.*; class H2O implements Runnable
{
static final Lock lock = new ReentrantLock();
static LinkedList<Condition> hQueue = new LinkedList<Condition>();
static LinkedList<Condition> oQueue = new LinkedList<Condition>(); private String particle;
private int id; public H2O(String particle, int id)
{
this.particle = particle;
this.id = id;
} public void run()
{
if (particle.equals("h"))
{
H(id);
}
else if (particle.equals("o"))
{
O(id);
}
} public static void H(int hid)
{
lock.lock();
try {
if (hQueue.size() >= 1 && oQueue.size() >= 1)
{
// generate water
Condition hc = hQueue.poll();
Condition oc = oQueue.poll();
hc.signal();
oc.signal();
System.out.println("H:" + hid);
}
else
{
// wait
Condition c = lock.newCondition();
hQueue.add(c);
c.await();
System.out.println("H:" + hid);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
} public static void O(int oid)
{
lock.lock();
try {
if (hQueue.size() >= 2)
{
// generate water
Condition hc1 = hQueue.poll();
Condition hc2 = hQueue.poll();
hc1.signal();
hc2.signal();
System.out.println("O:" + oid);
}
else
{
// wait
Condition c = lock.newCondition();
oQueue.add(c);
c.await();
System.out.println("O:" + oid);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
} } public class Solution {
public static void main(String args[]) throws InterruptedException {
for (int i = 1; i <= 6; i++)
{
new Thread(new H2O("h", i)).start();
}
Thread.sleep(1000);
for (int i = 1; i <= 6; i++)
{
new Thread(new H2O("o", i)).start();
}
Thread.sleep(1000);
for (int i = 7; i <= 36; i++)
{
new Thread(new H2O("h", i)).start();
}
Thread.sleep(1000);
for (int i = 7; i <= 12; i++)
{
new Thread(new H2O("o", i)).start();
}
Thread.sleep(1000);
for (int i = 13; i <= 18; i++)
{
new Thread(new H2O("o", i)).start();
}
}
}

  

H2O与Java线程同步的更多相关文章

  1. java 线程同步 原理 sleep和wait区别

    java线程同步的原理java会为每个Object对象分配一个monitor, 当某个对象(实例)的同步方法(synchronized methods)被多个线程调用时,该对象的monitor将负责处 ...

  2. Java线程同步_1

    Java线程同步_1 synchronized 该同步机制的的核心是同步监视器,任何对象都可以作为同步监视器,代码执行结束,或者程序调用了同步监视器的wait方法会导致释放同步监视器 synchron ...

  3. Java线程同步之一--AQS

    Java线程同步之一--AQS 线程同步是指两个并发执行的线程在同一时间不同时执行某一部分的程序.同步问题在生活中也很常见,就比如在麦当劳点餐,假设只有一个服务员能够提供点餐服务.每个服务员在同一时刻 ...

  4. java线程 同步临界区:thinking in java4 21.3.5

    java线程 同步临界区:thinking in java4 21.3.5 thinking in java 4免费下载:http://download.csdn.net/detail/liangru ...

  5. JAVA - 线程同步和线程调度的相关方法

    JAVA - 线程同步和线程调度的相关方法 wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁:wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等 ...

  6. Java线程同步的四种方式详解(建议收藏)

    ​ Java线程同步属于Java多线程与并发编程的核心点,需要重点掌握,下面我就来详解Java线程同步的4种主要的实现方式@mikechen 目录 什么是线程同步 线程同步的几种方式 1.使用sync ...

  7. Java线程同步和线程通信

    一.线程同步 当多个线程访问同一个数据时,非常容易出现线程安全问题.这时候就需要用线程同步. 不可变类总是线程安全的,因为它的对象状态是不可改变的,但可变类对象需要额外的方法来保证线程安全. 1.同步 ...

  8. 【总结】Java线程同步机制深刻阐述

    原文:http://hxraid.iteye.com/blog/667437 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread ...

  9. Java线程同步的方式

     java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查),      将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的 ...

随机推荐

  1. 理解Spark的RDD

    RDD是个抽象类,定义了诸如map().reduce()等方法,但实际上继承RDD的派生类一般只要实现两个方法: def getPartitions: Array[Partition] def com ...

  2. Android屏幕保持唤醒状态

    我们程序偶尔会有需要屏幕一直或较长时间的保持唤醒状态,而用户的睡眠时间又设置的比较短.这时可能会对程序以及用户的使用造成一定的影响.在Android中有两种方法,可以让我们在我们需要保持唤醒的页面长时 ...

  3. Centos搭建PHP5.3.8+Nginx1.0.9+Mysql5.5.17

    操作环境 操作系统:Mac Os Lion 虚拟主机:VMware Fusion 虚拟系统:Centos 5.5+ 操作用户:Root 实现目的:搭建LNMP环境. 安装依赖库和开发环境 #依赖库和开 ...

  4. ###STL学习--vector

    点击查看Evernote原文. #@author: gr #@date: 2014-08-11 #@email: forgerui@gmail.com vector的相关问题.<stl学习> ...

  5. Linux 网络相关命令

    1.修改ip,dns相关:sudo vi /etc/sysconfig/network-scripts/ifcfg-eth0 2.ifconfig 查找ip,mac地址 3.重启网络:sudo ser ...

  6. 第二十六篇、因为自定item(nav)而使系统右滑返回手势失效的解决方法

    @interface ViewController () <uigesturerecognizerdelegate> @end@implementation ViewController ...

  7. 第十篇、自定义UIBarButtonItem和UIButton block回调

    // 自定义导航栏左边按钮 self.navigationItem.leftBarButtonItem = [JQBlockedBarButtonItem blockedBarButtonItemWi ...

  8. String Shifting

    我们规定对一个字符串的shift操作如下:略去.shift(string, x) = string(0 <= x < n). 分析:一看这题,这不很简单么,直接模拟判断,但是这套路有这么简 ...

  9. Java如何获得平台相关的行分隔符、路径分隔符?

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3550194.html ,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体 ...

  10. 九度OJ 1510 替换空格

    题目地址:http://ac.jobdu.com/problem.php?pid=1510 题目描述: 请实现一个函数,将一个字符串中的空格替换成"%20".例如,当字符串为We ...