java线程 同步临界区:thinking in java4 21.3.5
java线程 同步临界区:thinking in java4 21.3.5
thinking in java 4免费下载:http://download.csdn.net/detail/liangrui1988/7580155
package org.rui.thread.critical;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 临界区
*
*
*
* Pair不是线程安全的,由于它的约束条件(尽管是随意的) 须要两个变量维护成同样的值。
* 此外,如本章前面所述,自添加操作不是线程安全的,
* 而且由于没有不论什么方法被标记为synchronized。所以不能保证一个pair对象在多线程程序中不会破坏.
* @author lenovo
*
*/
//org.rui.thread.critical.CriticalSection.java
class Pair
{
private int x,y;
public Pair(int x,int y)
{
this.x=x;
this.y=y;
}
public Pair(){this(0,0);}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void incrementX(){x++;}
public void incrementY(){y++;}
public String toString()
{
return "x: "+x+" , y:"+y;
}
/////////////////PariValuesNotEqualException
public class PariValuesNotEqualException extends RuntimeException
{
public PariValuesNotEqualException()
{
super("Pair values not equal:"+Pair.this);
}
}
//随意变,两个变量必须是平等的
//Arbitrary invariant --both variables must be equal:
public void checkState()
{
if(x!=y)
{
throw new PariValuesNotEqualException();
}
}
}//Pair end
//保护一对在一个线程安全的类
//protect a pair inside a thread -safe class:
abstract class PairManager
{
AtomicInteger checkCounter=new AtomicInteger(0);
protected Pair p=new Pair();
private List<Pair> storage=Collections.synchronizedList(new ArrayList<Pair>());
public synchronized Pair getPair()
{
//复制的原始安全:
//Make a copy to keep the original safe:
return new Pair(p.getX(),p.getY());
}
//如果这是一个耗时的操作
//Assume this is a time consuming operation
protected void store(Pair p)
{
storage.add(p);
try {
TimeUnit.MILLISECONDS.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//
public abstract void increment();
}
//整个同步方法
//synchronize the entire method
class PairManager1 extends PairManager
{
@Override
public synchronized void increment()
{
p.incrementX();
p.incrementY();
store(getPair());
}
}
//use a critical section: 使用临界区
class PairManager2 extends PairManager
{
public void increment()
{
Pair temp;
synchronized(this)
{
p.incrementX();
p.incrementY();
temp=getPair();
}
store(temp);
}
}
///操作者
class PairManipulator implements Runnable
{
private PairManager pm;
public PairManipulator(PairManager pm)
{
this.pm=pm;
}
@Override
public void run()
{
while(true)
pm.increment();
}
public String toString()
{
return "Pair: "+pm.getPair()+" checkCounter= "+pm.checkCounter.get();
}
}
////PairChecker
class PairChecker implements Runnable
{
private PairManager pm;
public PairChecker(PairManager pm)
{
this.pm=pm;
}
@Override
public void run() {
while(true)
{
pm.checkCounter.incrementAndGet();
pm.getPair().checkState();
}
}
}
/////////////////////////////////////////////////////////
public class CriticalSection {
//測试两种不同的方法
//test the two defferent approaches
static void testApproaches(PairManager pman1,PairManager pman2)
{
ExecutorService exec=Executors.newCachedThreadPool();
PairManipulator pm1=new PairManipulator(pman1);
PairManipulator pm2=new PairManipulator(pman2);
PairChecker pcheck1=new PairChecker(pman1);
PairChecker pcheck2=new PairChecker(pman2);
exec.execute(pm1);
exec.execute(pm2);
exec.execute(pcheck1);
exec.execute(pcheck2);
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
System.out.println("InterruptedException");
}
System.out.println("pm1:"+pm1+"\npm2:"+pm2);
System.exit(0);
}
public static void main(String[] args) {
PairManager pman1=new PairManager1(),
pman2=new PairManager2();
testApproaches(pman1,pman2);
}
}
/**output:(sample)
pm1:Pair: x: 8 , y:8 checkCounter= 674247
pm2:Pair: x: 8 , y:8 checkCounter= 5043736
*/
package org.rui.thread.critical;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 你还能够使用显示的lock对象来创建临界区
*
* 这里利用了CriticalSection.java的绝大部分,
* 并创建了新的使用显式的lock对象的PairManger类型。
* expliciPariManger2展示了怎样使用Lock对象来创建临界区,而对store()的调用则在这个临界区的外部
* @author lenovo
*
*/
//////////////////////////
class ExplicitPairManager1 extends PairManager {
private Lock lock =new ReentrantLock();
@Override
public synchronized void increment()
{
lock.lock();
try{
p.incrementX();
p.incrementY();
store(getPair());
}finally{
lock.unlock();
}
}
}
//use a critical section
class ExplicitPairManager2 extends PairManager
{
private Lock lock =new ReentrantLock();
@Override
public void increment() {
Pair temp=null;
lock.lock();
try{
p.incrementX();
p.incrementY();
temp=getPair();
}finally{
lock.unlock();
}
store(temp);
}
}
/////////////////
public class ExplicitCriticalSection {
public static void main(String[] args)
{
PairManager pman1=new PairManager1(),
pman2=new PairManager2();
CriticalSection.testApproaches(pman1,pman2);
}
}
/**
* output:
pm1:Pair: x: 10 , y:10 checkCounter= 195142
pm2:Pair: x: 11 , y:11 checkCounter= 4129459
*/
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlhbmdydWkxOTg4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlhbmdydWkxOTg4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
java线程 同步临界区:thinking in java4 21.3.5的更多相关文章
- Java线程同步之一--AQS
Java线程同步之一--AQS 线程同步是指两个并发执行的线程在同一时间不同时执行某一部分的程序.同步问题在生活中也很常见,就比如在麦当劳点餐,假设只有一个服务员能够提供点餐服务.每个服务员在同一时刻 ...
- java 线程同步 原理 sleep和wait区别
java线程同步的原理java会为每个Object对象分配一个monitor, 当某个对象(实例)的同步方法(synchronized methods)被多个线程调用时,该对象的monitor将负责处 ...
- Java线程同步_1
Java线程同步_1 synchronized 该同步机制的的核心是同步监视器,任何对象都可以作为同步监视器,代码执行结束,或者程序调用了同步监视器的wait方法会导致释放同步监视器 synchron ...
- 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允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), 将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的 ...
- Java线程同步(synchronized)——卖票问题
卖票问题通常被用来举例说明线程同步问题,在Java中,采用关键字synchronized关键字来解决线程同步的问题. Java任意类型的对象都有一个标志位,该标志位具有0,1两种状态,其开始状态为1, ...
随机推荐
- MockServer的测试思想与实现
转载:http://blog.csdn.net/shen1936/article/details/50298901 背景 什么是MOCK Mock的定义 Mock框架简介 Mock在单测中的应用 De ...
- vscode - 添加背景图片
首先,Ctrl+Shift+P安装backround , 而后重启vscode会有默认的背景图片 修改背景图,可自定义三张 具体请看gif图 最开始时,发现png根本不是全透明,用ps处理了一下(下列 ...
- TCP/IP 网络编程(五)
优于 select 的 epoll (I/O 复用) select 速度慢的原因 调用select后针对全部文件描写叙述符的循环 每次调用函数时都须要向该函数传递监视对象信息 select并非把发生变 ...
- Android 四大组件学习之Server一
上次学习了Android四大组件Activity之后,我们深刻理解了Activity.这次我们学习四大组件Service. Service与Activity的级别是一样的,都是Android系统不可缺 ...
- react-native flex 布局 详解
而在React Native中,有4个容器属性,2个项目属性,分别是: 容器属性:flexDirection flexWrap justifyContent alignItems 项目属性( ...
- 微博,and java 多线程编程 入门到精通 将cpu 的那个 张振华
http://down.51cto.com/data/2263476 java 多线程编程 入门到精通 将cpu 的那个 张振华 多个用户可以同时用一个 vhost,但是vhost之间是隔离的. ...
- index+small+row+if经典函数组合应用
EXCEL中index+small+row+if 函数组合可以查出满足同一条件的所有记录,通过实例讲解: 本文为原创,转载需标明出处,谢谢! 例:查找出一年级的所有班级及人数: A B C D 1 年 ...
- 使用ALAssetsLibrary读取所有照片
一. ALAssetsLibrary 介绍 ALAssetsLibrary 提供了访问iOS设备下”照片”应用下所有照片和视频的接口: 从 ALAssetsLibrary 中可读取所有的相册数据,即 ...
- linux watch命令
watch是一个非常实用的命令,基本所有的Linux发行版都带有这个小工具,如同名字一样,watch可以帮你监测一个命令的运行结果,省得你一遍遍的手动运行.在Linux下,watch是周期性的执行下个 ...
- HTML5 2D平台游戏开发#6地图绘制
此前已经完成了一部分角色的动作,现在还缺少可以交互的地图让游戏看起来能玩.不过在开始之前应当考虑清楚使用什么类型的地图,就2D平台游戏来说,一般有两种类型的地图,Tile-based和Art-base ...