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, ...
随机推荐
- mysql kill process解决死锁
mysql使用myisam的时候锁表比较多,尤其有慢查询的时候,造成死锁.这时需要手动kill掉locked的process.使他释放. (以前我都是重起服务)..惭愧啊.. 演示:(id 7是我用p ...
- rabbitmq 用户和授权
官方文档 https://my.oschina.net/hncscwc/blog/262246?p=
- springMVC 前后台日期格式传值解决方式之二(共二) @InitBinder的使用
关于springmvc日期问题的解决方式 除了本博客的[springMVC 前后台日期格式传值解决方式之 @DateTimeFormat的使用和配置]一文, 还有如下这种方式: 在Controller ...
- Mac 下Versions的 svn无法上传 .a 文件的问题
Xcode自带的svn和Versions以及一些其它工具都默认ignore".a"文件. 解决办法有两个: 方法一:使用命令行添加文件([转]原文在这) 1.打开终端,输入cd,空 ...
- android tooggle button
1 http://stackoverflow.com/questions/9938315/toggle-button-in-iphone-style 2 http://blog.csdn.net/bi ...
- js正则表达式的分组提取
- Online advertising术语
做项目发现非常多Online Advertising术语不懂,看代码感觉不那么清晰,如今来总结下遇到的一些术语. ---------------------------- 1. Online Adve ...
- 让 webpack 加载 Source Map
在浏览器中运行的 JavaScript 代码都是编译器输出的代码,这些代码的可读性很差.如果在开发过程中遇到一个不知道原因的 Bug,则你可能需要通过断点调试去找出问题. 在编译器输出的代码上进行断点 ...
- Spring Security三种认证
Spring Security: 1.用户名+密码认证 2.手机号+短信认证 Spring Social: 1.第三方认证, QQ登录等 Spring Security OAuth: 1.把认证之后的 ...
- 《HTML 5网页开发实例具体解释》样章、内容简单介绍、前言
http://spu.jd.com/1167757597.html http://product.dangdang.com/23484942.html 样章 http://download.csdn. ...