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, ...
随机推荐
- Java学习从入门到精通(1) [转载]
Java Learning Path (一).工具篇 一. JDK (Java Development Kit) JDK是整个Java的核心,包括了Java运行环境(Java Runtime Envi ...
- 如何从一个1G的文件中找到你所需要的东西
如何从一个1G的文件中找到你所需要的东西,这个问题貌似面试的时候会经常问到.不过不论你用什么语言,肯定逃脱不了按指针读或者按块读. 这里介绍python的用法.本人亲自实验了,速度还可以. 如果你的文 ...
- 转Python 标准库 urllib2 的使用细节
Python 标准库中有很多实用的工具类,但是在具体使用时,标准库文档上对使用细节描述的并不清楚,比如 urllib2 这个 HTTP 客户端库.这里总结了一些 urllib2 库的使用细节. 1 P ...
- Android 动画分析学习笔记
一:分类: Android动画分三种:view动画(对场景中的对象不断做图像变换<平移,缩放,旋转,透明度>).帧动画(顺序播放一系列图像产生动画效果).属性动画(动态改变对象属性). 二 ...
- docker 报错 Error response from daemon: driver failed programming external connectivity on endpoint mynginx
Error response from daemon: driver failed programming external connectivity on endpoint mynginx (7d1 ...
- 【Hadoop基础教程】2、Hadoop之单机模式搭建(转)
单机模式所需要的系统资源是最少的,这种安装模式下,Hadoop的core-site.xml.mapred-site.xml.hdfs-site.xml配置文件均为空.默认情况下,官方hadoop-1. ...
- Linux下Java、Maven、Tomcat的安装
1.安装Java(此处假定安装文件夹位/usr/local) 1)下载jdk(jdk-7),下载地址例如以下: 32位:http://download.oracle.com/otn-pub/java/ ...
- oracle海量数据中提升创建索引的速度
基本信息情况: 数据库版本:Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production 操作系统版本:Ce ...
- 机器学习12—FP-growth学习笔记
test12.py #-*- coding:utf-8 import sys sys.path.append("fpGrowth.py") import fpGrowth from ...
- 《TomCat与Java Web开发技术详解》(第二版) 第八章节的学习总结 -- 访问mysql
终于学到如何访问Mysql了 1. 可以看看此章节提供的sql脚本,以后可以照着写了.此外,对于Mysql如何使用,最好的地方就是其官网介绍了.http://dev.mysql.com/doc/ref ...