以下是一个普通线程代码:
package com.Sychronized; public class SychronizedDemo { //共享变量 private boolean ready=false; private int result=0; private int number=1; //写操作 public void write() { ready=true; //1.1 number=2; //1.2 } //读操作 public void read() { if(ready) //2.1 { result=number*3; //2.2 } System.out.println("result值为:"+result); } //内部线程类 private class ReadWriteThread extends Thread { //根据构造方法传入的flag参数,确定线程执行读操作还是写操作 private boolean flag; public ReadWriteThread(boolean flag) { this.flag=flag; } public void run() { if(flag) { //构造方法传入true,读操作 write(); } else { read(); } } } public static void main(String []args) { SychronizedDemo synDemo=new SychronizedDemo(); //启动线程执行写操作 synDemo.new ReadWriteThread(true).start(); synDemo.new ReadWriteThread(false).start(); } }
这段线程目标是输出6。
但是因为线程的执行顺序,可能导致不同的结果:
执行顺序:1.1-》2.1-》2.2-》1.2
结果:3
执行顺序,加上重排序的原因,导致先1.2,后1.1:1.2-》2.1-》2.2-》1.1
结果:0
可见性分析:
导致共享变量在线程间不可见的原因:
1)线程交叉执行
2)重排序结合交叉执行
3)共享变量更新后的值没在工作内存与主内存间及时更新。
安全的代码:
//写操作 public synchronized void write() { ready=true; number=2; } //读操作 public synchronized void read() { if(ready) { result=number*3; } System.out.println("result值为:"+result); }
synchronized解决方案:
1)保证原子性:(解决线程的交叉执行,同时解决了因为重排序加上交叉执行导致的结果)
2)可见性:(解决共享变量未及时更新)