JAVA多线程系列--关键字(volatile,synchronized)
来源:互联网 发布:sql拒绝访问 编辑:程序博客网 时间:2024/05/29 18:38
1.Synchronized
使用范围:1.对于普通同步方法,锁水当前实例对象
2.对于静态同步方法,锁是当前类的class对象
3.对于同步方法快,锁是synchonized内配置的对象
实现原理:JVM要保证每个monitorenter必须有对应的monitorexit与之配对。
任何对象都有一个monitor与之关联,当且一个monitor被持有后,它将处于锁定状态;直到monitor被释放。
例子:
/** * Synchronized 举例 * @author niyuelin * */public class SynchronizedExample { public Integer inc = 0; /** * 方法锁 */ public synchronized void increase1() { inc++; } /** * 代码块锁 */ public void increase2() { synchronized(this){ inc++; } } /** * 对象锁 */ public void increase3() { synchronized(inc.getClass()){ inc++; } } public static void main(String[] args) { final SynchronizedExample test = new SynchronizedExample(); System.out.println("========================111"); for (int i = 0; i < 10; i++) { new Thread() { public void run() { for (int j = 0; j < 1000; j++) test.increase3(); }; }.start(); } while (Thread.activeCount() > 2){ // 保证前面的线程都执行完 Thread.yield();// System.out.println(Thread.activeCount()); } System.out.println(test.inc); }}
1.volatile
内存语义:1.保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
2.禁止进行指令重排序。
实现原理: 1.lock前缀指令会引起处理器缓存回写到内存
2.一个处理器的缓存回写到内存会导致其他处理器的缓存无效
通俗的讲:Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。 但是Volatile不保证原子性
例子1:
public class TestWithVolatile { private static volatile boolean bChanged; public static void main(String[] args) throws InterruptedException { new Thread() { @Override public void run() { for (; ; ) { if (bChanged == !bChanged) { System.out.println("!="); System.exit(0); } } } }.start(); Thread.sleep(10); new Thread() { @Override public void run() { for (; ; ) { bChanged = !bChanged; } } }.start(); }}
输出:
若变量bChanged,有volatile修饰;则程序将立即结束并退出。
若无volatile修饰;则程序不会立即结束退出。
原因:每次使用它都到主存中进行读取,从而导致volatile修饰的值会不一样。
例子2:
/** * volatile不保证原子性 * @author niyuelin * */public class VolatileExample2 { public volatile int inc = 0; public void increase() { inc++; } public static void main(String[] args) { final VolatileExample2 test = new VolatileExample2(); for(int i=0;i<10;i++){ new Thread(){ public void run() { for(int j=0;j<1000;j++) test.increase(); }; }.start(); } while(Thread.activeCount()>2) //保证前面的线程都执行完 Thread.yield(); System.out.println(test.inc); } }
输出:
小于1000的值。
原因:volatile不保证原子性
阅读全文
0 0
- JAVA多线程系列--关键字(volatile,synchronized)
- java多线程之synchronized和volatile关键字
- Java关键字系列 — volatile、synchronized、lock
- Java多线程干货系列— volatile关键字
- java关键字volatile和synchronized在多线程中的应用
- Java——多线程总结、ThreadLocal/Volatile/synchronized/Atomic关键字
- java多线程编程关键字volatile,ThreadLocal和synchronized
- Java 多线程编程之synchronized 和 volatile关键字
- java 关键字synchronized和volatile
- Java多线程 synchronized关键字
- Java多线程-synchronized关键字
- Java 多线程 Synchronized关键字
- Java多线程-synchronized关键字
- 【java多线程 关键字】synchronized
- Java多线程 -- volatile关键字
- java多线程--volatile关键字
- Java 多线程:volatile关键字
- java 多线程 volatile 关键字
- Math 类BigDecimal 类型
- 【TCAX+AVS+MeGui】这里讲讲过气tcax内置特效的制作流程吧
- leetcode35. Search Insert Position
- 计算机组成原理
- CreateInstance(__uuidof(Connection)) 不支持此接口解决方法
- JAVA多线程系列--关键字(volatile,synchronized)
- python unittest单元测试
- 学习PyQt5(0)
- XListView请求网络数据
- 教你如何在中国区加速部署k8s,且实现自定义设置拥有k8s镜像的仓库与其命名空间
- 圆和长方形面积
- 精妙绝伦的脑洞acm题
- Linux
- 新用户如何获得阿里云优惠怎么才能省钱-写给阿里云新手