1. 写方法【requestStop】和读方法【stopRequested】都被同步了。如果读和写操作没有都被同步,同步就不会起作用。《Effective Java中文版 第二版 Page231》<v1.0>
public class StopThread{
private static boolean stopRequested;
private static synchronized void requestStop(){
stopRequested = true;
}
private static synchronized boolean stopRequested(){
return stopRequested;
}
public static void main(String[] args) throws InterruptedException{
Thread backgroundThread=new Thread(new Runnable){
public void run(){
int i=0;
while(!stopRequested())
i++;
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
requestStop();
}
}
下面看另一种实现同步的方法:
【虽然volatile修饰符不执行互斥访问,但它可以保证任何一个线程在读取该域的时候都将看到最近刚刚被写入的值:】
//cooperative thread termination with a volatile field
public class StopThread{
private static volatileboolean stopRequested;
public static void main(String[] args){
Thread backgroundThread =new Thread(new Runnable(){
public void run(){
int i=0;
while(!stopRequested)
i++
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested=true;
}
}
2:java中同步工具类:Semaphore【信号量】,cycleBarrier【可重用栅栏】,CountDownLatch【倒计数门闸锁】,Exchange 见优秀博客:http://blog.csdn.net/dlf123321/article/details/51382503
Exchanger可以在两个线程之间交换数据,只能是2个线程,他不支持更多的线程之间互换数据。
当线程A调用Exchange对象的exchange()方法后,他会陷入阻塞状态,直到线程B也调用了exchange()方法,然后以线程安全的方式交换数据,之后线程A和B继续运行
- ackage cn.itcast.heima2;
- import java.util.concurrent.Exchanger;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- public class ExchangerTest {
- public static void main(String[] args) {
- ExecutorService service = Executors.newCachedThreadPool();
- final Exchanger<String> exchanger = new Exchanger<String>();
- service.execute(new Runnable(){
- public void run() {
- try {
- String data1 = "zxx";
- System.out.println("线程" + Thread.currentThread().getName() +
- "正在把数据" + data1 +"换出去");
- Thread.sleep((long)(Math.random()*10000));
- String data2 = (String)exchanger.exchange(data1);
- System.out.println("线程" + Thread.currentThread().getName() +
- "换回的数据为" + data2);
- }catch(Exception e){
- }
- }
- });
- service.execute(new Runnable(){
- public void run() {
- try {
- String data1 = "lhm";
- System.out.println("线程" + Thread.currentThread().getName() +
- "正在把数据" + data1 +"换出去");
- Thread.sleep((long)(Math.random()*10000));
- String data2 = (String)exchanger.exchange(data1);
- System.out.println("线程" + Thread.currentThread().getName() +
- "换回的数据为" + data2);
- }catch(Exception e){
- }
- }
- });
- }
- }