java多线程总结四:volatile、synchronized示例
2011-10-28 14:20
337 查看
1、synchronized保证同步
先看一个生成偶数的类
注意到在产生偶数是要加同步锁,否则可能线程1刚好执行了一句++currentEvenValue;操作,就被线程2抢去了cpu,此时线程2执行return currentEvenValue;这时返回的就是一个奇数。加synchronized
就是两个线程同时只能一个线程执行synchronized 块的代码。
测试代码:
分析:如果产生偶数的类未加synchronized,那么测试程序将会出现奇数导致退出程序。
2、volatile表示原子性,可见性。
对于多个线程之间共享的变量,每个线程都有自己的一份拷贝,当线程1改变变量值时,其他线程并不马上知道该变量值改变了,volatile就保证了变量值对各个线程可见,一个线程改变该值,马上其他线程中该值也改变。原子性表明操作不可中断,如基本变量赋值。
代码示例:
注意i++操作并不是原子行操作,getValue() 方法也要加synchronized 。
先看一个生成偶数的类
package demo.thread; /** *这是一个int生成器的抽象类 * */ public abstract class IntGenerator { private volatile boolean canceled = false; public abstract int next(); public void cancel() { canceled = true; } public boolean isCanceled() { return canceled; } }
/* * 产生偶数 */ class EvenGenerator extends IntGenerator { private int currentEvenValue = 0; String s = ""; @Override public int next() { synchronized (s) { ++currentEvenValue; ++currentEvenValue; return currentEvenValue; } } // //这样也可以 // public synchronized int next() { // ++currentEvenValue; // ++currentEvenValue; // return currentEvenValue; // } }
注意到在产生偶数是要加同步锁,否则可能线程1刚好执行了一句++currentEvenValue;操作,就被线程2抢去了cpu,此时线程2执行return currentEvenValue;这时返回的就是一个奇数。加synchronized
就是两个线程同时只能一个线程执行synchronized 块的代码。
测试代码:
package demo.thread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /* * 消费数字 */ 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 enen!"); generator.cancel(); } } } public static void test(IntGenerator gp, int count) { ExecutorService exec = Executors.newCachedThreadPool(); for (int i = 0; i < count; i++) exec.execute(new EvenChecker(gp, i)); exec.shutdown(); } public static void test(IntGenerator gp) { test(gp, 10); } public static void main(String[] args) { test(new EvenGenerator()); } }
分析:如果产生偶数的类未加synchronized,那么测试程序将会出现奇数导致退出程序。
2、volatile表示原子性,可见性。
对于多个线程之间共享的变量,每个线程都有自己的一份拷贝,当线程1改变变量值时,其他线程并不马上知道该变量值改变了,volatile就保证了变量值对各个线程可见,一个线程改变该值,马上其他线程中该值也改变。原子性表明操作不可中断,如基本变量赋值。
代码示例:
package demo.thread; public class VolatileDemo implements Runnable { private volatile int i = 0;//volatile设置可见性 public synchronized int getValue() { return i; } private synchronized void enenIncrement() { i++; i++; } @Override public void run() { while (true) enenIncrement(); } public static void main(String[] args) { VolatileDemo at = new VolatileDemo(); new Thread(at).start(); while (true) { int val = at.getValue(); if (val % 2 != 0) {//出现奇数,退出程序 System.out.println(val+" is not enen!"); System.exit(0); } } } }
注意i++操作并不是原子行操作,getValue() 方法也要加synchronized 。
相关文章推荐
- java多线程总结四:volatile、synchronized示例
- java多线程总结四:volatile、synchronized示例
- Java——多线程总结及ThreadLocal、Volatile、synchronized、Atomic四个关键字
- java多线程:volatile及Timer用法示例
- java多线程总结四:volatile、synchronized示例
- Java多线程总结之由synchronized说开去(转)
- java多线程总结三:sleep()、join()、interrupt()示例
- java多线程总结三:sleep()、join()、interrupt()示例
- java多线程之内存可见性-synchronized、volatile
- java多线程总结三:sleep()、join()、interrupt()示例
- java多线程总结三:sleep()、join()、interrupt()示例
- java多线程中synchronized(同步块)和volatile的区别
- (JAVA)对volatile和synchronized以及join()的理解和总结
- Java 多线程编程之synchronized 和 volatile关键字
- 【转】Java多线程编程中易混淆的3个关键字( volatile、ThreadLocal、synchronized)总结
- JAVA多线程之volatile 与 synchronized 的比较
- 【Java多线程】-线程同步synchronized和volatile
- JAVA多线程之volatile 与 synchronized 的比较
- 高级java必会系列二:多线程经常使用的3个关键字:synchronized、ReentrantLock、volatile
- Java之多线程内存可见性_3(synchronized和volatile比较)