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允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), 将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的 ...
随机推荐
- Activti跳过中间节点的helloworld实例程序
http://blog.csdn.net/songzheng_741/article/details/17289633 此实例是一个最简单的在运行时人为动态改变流程运转的实例,意在为任意流.驳回等功能 ...
- SqLite 框架 GreenDAO
GreenDAO: 会生成一个数据访问,不用我们书写访问数据库的代码: 核心原理图 生成代码 就是用生成器生成一个对应的java类的生成工厂 public static void main(Strin ...
- phpize php扩展模块安装
安装(fastcgi模式)的时候,常常有这样一句命令:/usr/local/webserver/php/bin/phpize一.phpize是干嘛的?phpize是什么东西呢?php官方的说明:htt ...
- java多线程总结六:经典生产者消费者问题实现
这是个线程同步的经典例子,源代码如下: <span style="font-size:16px;">package demo.thread; /** *经典生产者与消费 ...
- WCF编程系列(五)元数据
WCF编程系列(五)元数据 示例一中我们使用了scvutil命令自动生成了服务的客户端代理类: svcutil http://localhost:8000/?wsdl /o:FirstServic ...
- jquery load
$('#loadFooter').click(function() { $('#footer').load('footer.html'); });
- C--指针函数,static
(*p)是固定写法,代表指针的变量P将来是指向函数 void (*p)(); p=test;//指针变量P指向了test函数 函数名test代表函数地址 //同等调用test()函数 (*p)(); ...
- JavaScript 学习笔记: 扩充类型的功能
JavaScript 是允许给基本类型扩充功能的.例如,可以通过对Object.prototype增加方法,可以让该方法对所有的对象都可用. 这样的方式对函数,数组,字符串,数字,正则表达式和布尔值同 ...
- 理解css 中的position五个属性
在实际开发页面布局时,运用position,对定位的块级元素的嵌套的效果总是不太理解,这里做了几个测试 一般的在w3c中我们可以很容易的获取定义: static : 默认值.没有定位,元素出现在正常的 ...
- Spring框架中的单例Beans是线程安全的么?
Spring框架并没有对单例bean进行任何多线程的封装处理.关于单例bean的线程安全和并发问题需要开发者自行去搞定.但实际上,大部分的Spring bean并没有可变的状态(比如Serview类和 ...