首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

java多线程小结四:volatile、synchronized示例

2012-10-20 
java多线程总结四:volatile、synchronized示例1、synchronized保证同步先看一个生成偶数的类?package demo.t

java多线程总结四:volatile、synchronized示例

1、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 = "";@Overridepublic int next() {<span style="color:#ff0000;">synchronized </span>(s) {++currentEvenValue;++currentEvenValue;return currentEvenValue;}}////这样也可以//public <span style="color:#ff0000;">synchronized </span>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++;}@Overridepublic 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 。

热点排行