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; /** * synchronized关键字不能尝试着获取锁且最终获取锁会失败 * 或都尝试获取一段时间 ,然后放弃它,要实现这些,你必须使用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 */
java线程共享受限资源 解决资源竞争 thinking in java4 21.3,布布扣,bubuko.com
java线程共享受限资源 解决资源竞争 thinking in java4 21.3
原文:http://blog.csdn.net/liangrui1988/article/details/37584285