public abstract class IntGenerator {
private volatile boolean canceled = false;
public abstract int next( );
public void cancle( ) { canceled = true; }
public boolean isCanceled( ) { return canceled; }
}public class EvenChecker implements Runnable {
private IntGenerator generator;
private final int id;
public EvenChecker(IntGenerator g , int ident) {
generator = g;
id = ident;
}
public void run() {
while( !generator.isCanceled() ) {
int val = generator.next();
if(val % 2 != 0) {
System.out.println(val + "not even!");
generator.cancle();
}
}
}
public static void test(IntGenerator gp, int count) {
System.out.println("Press Control -C to exit");
ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < 10;i++)
exec.execute(new EvenChecker(gp, i));
exec.shutdown();
}
public static void test(IntGenerator gp) {
test(gp, 10);
}
}public class EvenGenerator extends IntGenerator {
private int currentEvenValue = 0;
public int next() {
++currentEvenValue;
++currentEvenValue;
return currentEvenValue;
}
public static void main(String []args) {
EvenChecker.test(new EvenGenerator());
}
}在使用并发时,将域设置为private是很重要的。这是一种保证。保证没有其它任务能够直接訪问到该域。
JVM负责跟踪对象被加锁的次数。假设一个对象被解锁(即锁被全然释放),其计数变为0。
假设对该资源的訪问是复合操作,即使共享对象自身是线程安全的,也无法保证数据的一致性,比如:if( put(**))这样的操作。就必需要把复合操作所有包括在锁内,对于存在多个对象的共享。假设相互之间有状态的关联,这样的处理方式依旧有效。
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());
}
}public class MutexEvenGenerator extends IntGenerator {
public int currentEvenValue = 0;
private Lock lock = new ReentrantLock();
@Override
public int next() {
lock.lock();
try {
++currentEvenValue;
++currentEvenValue;
return currentEvenValue;
} finally {
lock.unlock();
}
}
public static void main(String []args) {
EvenChecker.test( new MutexEvenGenerator( ));
}
}当你在使用Lock对象时,有一些原则须要被记住:你必须放置在finally子句中带有unlock()的try-finally语句,以避免该锁被无限期锁住。
注意,return语句必须在try子句中出现,以确保unlock()不会过早发生,从而将数据暴露给第二个任务。
public class MyMutexTest {
private static Lock lock = new ReentrantLock();
public static void main(String args[]) {
new Thread( new Runnable() {
public void run() {
lock.lock();
while(true);
}
}).start();
new Thread(new Runnable() {
public void run() {
if( lock.tryLock() == false ) {
System.out.println("acquire lock failed 1");
}
}
}).start();;
new Thread( new Runnable() {
public void run() {
try {
if(lock.tryLock(2, TimeUnit.SECONDS) == false) {
System.out.println("acquire lock failed 2");
}} catch (InterruptedException e) {
}
}
}).start();
}
}public class MyVisibilityTest implements Runnable{
private static boolean mv = false;
private static int integer = 0;
@Override
public void run() {
while(true) {
if(mv == true) {
System.out.println(integer);
return;
}
}
}
public static void main(String []args) {
new Thread(new MyVisibilityTest()).start();
integer = 34;
mv = true;
}
}假设在仅仅共享一个对象的前提下。它为你提供了一种将线程间的复合操作转为线程安全操作的机会。
public class AtomicEvenGenerator extends IntGenerator {
private AtomicInteger currentEvenValue = new AtomicInteger(0);
public int next() {
return currentEvenValue.addAndGet(2);
}
public static void main(String args[]) {
EvenChecker.test(new AtomicEvenGenerator());
}
} sychronized如何才干不使用额外的一个对象进行加锁?办法就是对this加锁,假设多个线程运行的是同一任务,使用sychronized是不错的选择。由于它能够避免你显式的定义和使用一个Lock。
class ContextThread {
private static ThreadLocal<Integer> value = new ThreadLocal<Integer>();
public static void setInteger(Integer value){
ContextThread.value.set(value);
}
public static Integer getInteger() {
return value.get();
}
public static void increment() {
value.set(value.get() + 1);
}
}
public class ThreadLocalTest {
public static void main(String []args) {
for(int i = 0; i < 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
ContextThread.setInteger(0);
ContextThread.increment();
System.out.println( ContextThread.getInteger() );
}
}).start();
}
}
}原文:http://www.cnblogs.com/gcczhongduan/p/5153692.html