H2O与Java线程同步
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线程同步的更多相关文章
- java 线程同步 原理 sleep和wait区别
java线程同步的原理java会为每个Object对象分配一个monitor, 当某个对象(实例)的同步方法(synchronized methods)被多个线程调用时,该对象的monitor将负责处 ...
- Java线程同步_1
Java线程同步_1 synchronized 该同步机制的的核心是同步监视器,任何对象都可以作为同步监视器,代码执行结束,或者程序调用了同步监视器的wait方法会导致释放同步监视器 synchron ...
- Java线程同步之一--AQS
Java线程同步之一--AQS 线程同步是指两个并发执行的线程在同一时间不同时执行某一部分的程序.同步问题在生活中也很常见,就比如在麦当劳点餐,假设只有一个服务员能够提供点餐服务.每个服务员在同一时刻 ...
- java线程 同步临界区:thinking in java4 21.3.5
java线程 同步临界区:thinking in java4 21.3.5 thinking in java 4免费下载:http://download.csdn.net/detail/liangru ...
- JAVA - 线程同步和线程调度的相关方法
JAVA - 线程同步和线程调度的相关方法 wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁:wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等 ...
- Java线程同步的四种方式详解(建议收藏)
Java线程同步属于Java多线程与并发编程的核心点,需要重点掌握,下面我就来详解Java线程同步的4种主要的实现方式@mikechen 目录 什么是线程同步 线程同步的几种方式 1.使用sync ...
- Java线程同步和线程通信
一.线程同步 当多个线程访问同一个数据时,非常容易出现线程安全问题.这时候就需要用线程同步. 不可变类总是线程安全的,因为它的对象状态是不可改变的,但可变类对象需要额外的方法来保证线程安全. 1.同步 ...
- 【总结】Java线程同步机制深刻阐述
原文:http://hxraid.iteye.com/blog/667437 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread ...
- Java线程同步的方式
java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), 将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的 ...
随机推荐
- Linux find常见用法示例
find命令的参数: pathname: find命令所查找的目录路径.例如用.来表示当前目录,用/来表示系统根目录.-print: find命令将匹配的文件输出到标准输出.-exec: find命令 ...
- ASP.NET 上传图片添加文字、Logo水印
http://www.cnblogs.com/xvqm00/archive/2010/06/22/1762783.html
- [转]如何学好windows c++编程 学习精髓(收集,整理)
以下是很多VC爱好者的学习经历,希望对大家有所帮助: 我记得我在网上是这么说的:先学win32的SDK,也就是API, 再学MFC,这么一来呢,就先有个基础,MFC是API的封装, 如果API用的熟了 ...
- UDP 多播 Java
1.服务端 public class UdpMulticastServer { /** * @param args */ public static void main(String[] args) ...
- Java机试题目_怎样截取字符串
面试题1 怎样截取字符串 考题题干 编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串.但是要保证汉字不被截半个,如"我ABC"4,应该截为" ...
- TCP/IP协议三次握手与四次握手流程解析(转载及总结)
原文地址:http://www.2cto.com/net/201310/251896.html,转载请注明出处: TCP/IP协议三次握手与四次握手流程解析 一.TCP报文格式 TCP/IP协议的详 ...
- ios registerNib: and registerClass:
先看看apple官网简述: registerNib:forCellWithReuseIdentifier: Register a nib file for use in creating new co ...
- iOS开发——手机号,密码,邮箱,身份证号,中文判断
目前这些方面的判断主要是用了正则表达式 手机号的判断,目前主要是长度.均是数字,支持的号段由于第三方通讯比如京东通讯,小米通讯等支持的号段挺多, 有171,170,135,147等等,所以号段限制简单 ...
- C++重写与重载、重定义
文章引用自:http://blog.163.com/clevertanglei900@126/blog/static/111352259201102441934870/ 重载overload:是函数名 ...
- nginx 默认会把header里的参数去掉下划线
做token验证的时候遇到问题:在本地可以获取前端header传的参数,但是部署到服务器获取的就是null(服务器地址用nginx做了代理) 原因: nginx代理默认会把header的参数的 &qu ...