java线程共享受限资源 解决资源竞争 具体介绍请參阅:thinking in java4 21.3
thinking in java 4免费下载:http://download.csdn.net/detail/liangrui1988/7580155
package org.rui.thread.res;
/**
* 不对的訪问 资源
* @author lenovo
*
*/
public abstract class IntGenerator {
private volatile boolean canceled=false;//取消的
public abstract int next();
// 同意这样的被取消
public void cancel(){canceled =true;}
public boolean isCanceled(){return canceled;}
}
package org.rui.thread.res;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 不论什么IntGenerator都能够用以下的EvenCherker类来測试
* @author lenovo
*
*/
public class EvenChecker implements Runnable {
private IntGenerator generator;
private final int id;
public EvenChecker(IntGenerator g,int ident)
{
this.generator=g;
this.id=ident;
}
@Override
public void run() {
while(!generator.isCanceled())
{
int val=generator.next();
if(val%2!=0)
{
System.out.println(val+" not even!");
generator.cancel();//cancels all evencheckers
}
}
}
///test any type of intgenerator
public static void test(IntGenerator gp,int count)
{
System.out.println("press control-c to exit");
ExecutorService ex=Executors.newCachedThreadPool();
for(int i=0;i<count;i++)
{
ex.execute(new EvenChecker(gp,i));
}
ex.shutdown();
/*for(int i=0;i<count;i++)
{
Thread t=new Thread(new EvenChecker(gp,i));
t.start();
}*/
}
///
public static void test(IntGenerator gp)
{
test(gp,10);
}
}
package org.rui.thread.res;
/**
* 这个程序终于会失败,由于evenChecker任务在evenGenerator处于 不恰当的 状态时
* 仍可以訪问当中信息
* 假设你希望更快地发现失败。可以尝试着将yield() 的调用放置到第一个和第二个递增操作之间。
* 这仅仅是并发程序的部分部题
* @author lenovo
*
*/
public class EvenGenerator extends IntGenerator {
private int currentEvenValue=0;
@Override
public int next() {
++currentEvenValue;//危急项目》的出版物! danger point here
++currentEvenValue;
return currentEvenValue;
}
public static void main(String[] args) {
EvenChecker.test(new EvenGenerator());
}
}
/**
* output:
press control-c to exit
13103419 not even!
*/
package org.rui.thread.res;
/**
* 同步控制 EvenGenerator
* @author lenovo
*
*/
public class SynchronizedEvenGenerator extends IntGenerator {
private int currentEvenValue=0;
@Override
public synchronized int next() {
++currentEvenValue;
Thread.yield();//导致失败的更快 暂停当前正在运行的线程对象。并运行其它线程。
++currentEvenValue;
return currentEvenValue;
}
public static void main(String[] args) {
EvenChecker.test(new SynchronizedEvenGenerator());
}
}
/**
output:
press control-c to exit
*/
package org.rui.thread.res;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 使用显示的Lock对象
* @author lenovo
*
*/
public class MutexEvenGenerator extends IntGenerator {
private int currentEvenValue=0;
Lock lock=new ReentrantLock();
@Override
public int next() {
lock.lock();
try {
++currentEvenValue;
Thread.yield();//导致失败的更快 暂停当前正在运行的线程对象,并运行其它线程。
++currentEvenValue;
return currentEvenValue;
} finally
{
lock.unlock();
}
}
//////////////////////////////
public static void main(String[] args)
{
EvenChecker.test(new MutexEvenGenerator());
}
}
/**
output:
press control-c to exit
*/
package org.rui.thread.res;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* synchronizedkeyword不能尝试着获取锁且终于获取锁会失败
* 或都尝试获取一段时间 。然后放弃它。要实现这些。你必须使用concurrent类库:
*
*
* ReentrantLock同意你尝试着获取但终于末获取锁,这样假设其它人已经获取了这个锁,
* 那么你就能够决定离开去运行其它一些事件。而不是等待直至这个锁被释放,就像在untimed()方法中所示。
* 在timed中 做出尝试去获取锁。该尝试能够在2秒之后失败
* @author lenovo
*
*/
public class AttemptLocking {
//可重入的相互排斥锁
private ReentrantLock lock=new ReentrantLock();
public void untimed()//不计时的
{
// 仅在调用时锁未被还有一个线程保持的情况下。才获取该锁。
boolean captured=lock.tryLock();
try
{
System.out.println("tryLock(): "+captured);
} finally
{
if(captured)
lock.unlock();
}
}
/////////////
public void timed()//计时
{
boolean captured=false;
try {
//假设锁在给定等待时间内没有被还有一个线程保持,且当前线程未被中断,则获取该锁。
captured=lock.tryLock(2,TimeUnit.SECONDS);
} catch(InterruptedException e)
{
throw new RuntimeException(e);
}
try
{
System.out.println("tryLock(2,TimeUnit.SECONDS) : "+captured);
} finally
{
if(captured)
lock.unlock();
}
}
///////////////main
public static void main(String[] args) throws InterruptedException {
final AttemptLocking al=new AttemptLocking();
al.untimed();//true -- lock is available 锁可用
al.timed();//true -- lock is available
//如今创建一个单独的任务获取锁 使以下的线程调用产生竞争
new Thread()
{
{setDaemon(true);}
@Override
public void run() {
al.lock.lock();
System.out.println("acquired");
}
}.start();
Thread.sleep(1000);
// 暂停当前正在运行的线程对象,并运行其它线程。
//Thread.yield();//give the 2nd task a chance 给第二个任务一个机会
al.untimed();//false--lock grabbed by task 锁了的任务
al.timed();//false--lock grabbed by task
}
}
/**
* output:
tryLock(): true
tryLock(2,TimeUnit.SECONDS) : true
acquired
tryLock(): false
tryLock(2,TimeUnit.SECONDS) : false
*/