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. 过滤网页中HTML代码的ASP函数

    Function LoseHtml(ContentStr) Dim ClsTempLoseStr,regEx ClsTempLoseStr = Cstr(ContentStr) Set regEx = ...

  2. SQL 拼接多个字段的值&一个字段多条记录的拼接 [轉]

    例如student表: studentID studentName studentScore 01 Alice 90 02 Bill 95 03 Cindy 100 一.拼接多个字段的值 select ...

  3. ACM——搜索(一)

    南邮OJ——1108 搜索(一) 时间限制(普通/Java):3500MS/10500MS          运行内存限制:65536KByte总提交:1023            测试通过:367 ...

  4. build-essential

  5. asp.net MVC URL路由入门指南

    asp.net MVC 的URL路由是一个非常强大的功能,而且有个优点:强大单不复杂.然而,目前我在网上看到的相关资料,却都仅仅提供一些示例,仅通过这些示例,初学者基本上不可能明白为什么要这么配置,更 ...

  6. C# ACM poj1003

    这题很有内涵,先用简单方法 public static void acm1003(double a) { ) { return; } ; ) { / b; a = a - c; b++; } Cons ...

  7. NOIP(提高组)DAY1国王游戏

    问题描述 恰逢H国国庆,国王邀请n位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这n位大臣排成一排,国王站在队伍的最前面.排好队 ...

  8. 使用Notepad++将多行数据合并成一行

    1.按Ctrl+F,弹出“替换”的窗口: 2.选择“替换”菜单: 3.“查找目标”内容输入为:\r\n: 4.“替换为”内容为空: 5.“查找模式”选择为正则表达式: 6.设置好之后,点击“全部替换” ...

  9. Vsftpd -- 验证方式

    vsftpd程序提供的FTP服务可选认证方式,分别为匿名访问.本地用户和虚拟用户: 匿名访问:任何人无需验证口令即可登入FTP服务端. 本地用户:使用FTP服务器中的用户.密码信息. 虚拟用户:创建独 ...

  10. html5新增标签兼容性

    很多低版本的浏览器是不识html5新增的标签的,所以为了解决浏览器兼容性问题,主要有两种方法: js可以创建我们自定义的标签,例如,我们可以用js语句 document.createElement(' ...