java多线程总结四:volatile、synchronized示例
来源:互联网 发布:不是方阵有逆矩阵吗 编辑:程序博客网 时间:2024/05/22 14:57
1、synchronized保证同步
先看一个生成偶数的类
- <span style="font-size:16px;">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;
- }
- }
- </span>
- <span style="font-size:16px;">/*
- * 产生偶数
- */
- class EvenGenerator extends IntGenerator {
- private int currentEvenValue = 0;
- String s = "";
-
- @Override
- public 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;
- // }
- }</span>
注意到在产生偶数是要加同步锁,否则可能线程1刚好执行了一句++currentEvenValue;操作,就被线程2抢去了cpu,此时线程2执行return currentEvenValue;这时返回的就是一个奇数。加synchronized就是两个线程同时只能一个线程执行synchronized块的代码。
测试代码:
- <span style="font-size:16px;">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());
- }
- }</span>
分析:如果产生偶数的类未加synchronized,那么测试程序将会出现奇数导致退出程序。
2、volatile表示原子性,可见性。
对于多个线程之间共享的变量,每个线程都有自己的一份拷贝,当线程1改变变量值时,其他线程并不马上知道该变量值改变了,volatile就保证了变量值对各个线程可见,一个线程改变该值,马上其他线程中该值也改变。原子性表明操作不可中断,如基本变量赋值。
代码示例:
- <span style="font-size:16px;">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);
- }
- }
-
- }
- }
- </span>
注意i++操作并不是原子行操作,getValue() 方法也要加synchronized 。
1、synchronized保证同步
先看一个生成偶数的类
- <span style="font-size:16px;">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;
- }
- }
- </span>
- <span style="font-size:16px;">/*
- * 产生偶数
- */
- class EvenGenerator extends IntGenerator {
- private int currentEvenValue = 0;
- String s = "";
- @Override
- public 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;
- // }
- }</span>
注意到在产生偶数是要加同步锁,否则可能线程1刚好执行了一句++currentEvenValue;操作,就被线程2抢去了cpu,此时线程2执行return currentEvenValue;这时返回的就是一个奇数。加synchronized就是两个线程同时只能一个线程执行synchronized块的代码。
测试代码:
- <span style="font-size:16px;">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());
- }
- }</span>
分析:如果产生偶数的类未加synchronized,那么测试程序将会出现奇数导致退出程序。
2、volatile表示原子性,可见性。
对于多个线程之间共享的变量,每个线程都有自己的一份拷贝,当线程1改变变量值时,其他线程并不马上知道该变量值改变了,volatile就保证了变量值对各个线程可见,一个线程改变该值,马上其他线程中该值也改变。原子性表明操作不可中断,如基本变量赋值。
代码示例:
- <span style="font-size:16px;">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);
- }
- }
- }
- }
- </span>
注意i++操作并不是原子行操作,getValue() 方法也要加synchronized 。
- java多线程总结四:volatile、synchronized示例
- java多线程总结四:volatile、synchronized示例
- java多线程总结四:volatile、synchronized示例
- Java——多线程总结、ThreadLocal/Volatile/synchronized/Atomic关键字
- Java多线程volatile和synchronized
- 多线程总结(四)volatile
- JAVA多线程编程---volatile与synchronized
- 【Java多线程】-线程同步synchronized和volatile
- java多线程(一) volatile与synchronized区别
- Java多线程之synchronized和volatile
- JAVA多线程同步:volatile,synchronized,Atomic... 比较
- 【转载】java多线程synchronized volatile解析
- java多线程之synchronized和volatile关键字
- java多线程二(synchronized与volatile)
- JAVA多线程系列--关键字(volatile,synchronized)
- Java并发基础(四)-volatile和synchronized
- java多线程系列四:synchronized
- 多线程 synchronized volatile CAS
- 浅谈C语言 extern 指针与数组
- Linux下部署多个Tomcat
- 常用正则表达式
- [poj 2524]Ubiquitous Religions[并查集]
- java多线程总结五:线程池的原理及实现
- java多线程总结四:volatile、synchronized示例
- TextView使用SpannableString设置复合文本 + android弹出窗口的实现(PopupWindow)
- java多线程总结三:sleep()、join()、interrupt()示例
- java多线程总结二:后台线程(守护线程)
- android点餐系统
- java多线程总结一:线程的两种创建方式及优劣比较
- 第7章 图——最短路径之某个源点到其余各顶点的最短路径
- Hibernate性能:fetching策略
- 如何让推销BI产品