synchronized和volatile

来源:互联网 发布:表示公司的顶级域名 编辑:程序博客网 时间:2024/05/17 08:18

java线程的两个特性:可见性和有序性。
可见性:多线程之间不可直接交互,只能通过共享变量来实现。多线程之间共享一个对象例如C,这个对象被创建在主内存(堆内存)中,创建每个线程都会创建相应的工作内存(线程栈)。工作内存存储了主内存中对象C,线程操作C对象时,先从主内存中复制C对象到工作内存中再进行操作。当C在多个工作内存中都存在副本时,如果一个线程修改了共享变量,其他线程也能够看到被修改后的值,这成为可见性。
有序性:不同线程之间按序完成各自相应的操作,相互之间不产生影响,此为有序性。

解决多线程同步问题:一、使用synchronized将需要互斥的代码包含起来(或者将整个方法包起来),synchronized既保证了多线程的并发有序性,又保证了多线程的内存可见性。 每个锁对(JLS中叫monitor)都有两个队列,一个是就绪队列,一个是阻塞队列,就绪队列存储了将要获得锁的线程,阻塞队列存储了被阻塞的线程,当一个线程被唤醒(notify)后,才会进入到就绪队列,等待CPU的调度,反之,当一个线程被wait后,就会进入阻塞队列,等待下一次被唤醒。一个线程执行互斥代码过程如下:1、 获得同步锁;2、清空工作内存;3、从主内存拷贝对象副本到工作内存;4、执行代码(计算或者输出等);5、 刷新主内存数据;6、释放同步锁。

public class Test {      public static void main(String[] args) {          Writer writer= new Writer();          new Thread() {              public void run() {                  writer.writer("aaaaaaaaaaaaaaa");              };          }.start();                new Thread() {              public void run() {                  writer.writer("bbbbbbbbbbbbbbbbb");              };          }.start();      }  }  class Writer {      public (**synchronized**) void writer(String str) {          //逐个输出name的每个字符          **synchronized(this)**{            for(int i = 0; i < str.length(); i++) {                  System.out.print(str.charAt(i));              }          }    }  }  

二、volatile修饰变量,在这种情况下内存模型(主内存和线程工作内存)确保所有线程可以看到一致的变量值。加上volatile可以将共享变量i和j的改变直接响应到主内存中,这样保证了主内存中i和j的值一致性,但不能保证并发有序性。若在执行two方法的时候在已获取到i的值正在获取j的值的这一期间,one方法被执行了很多次将导致输出结果j比i大。

public class Test {      static volatile int i = 0, j = 0;      static void one() {          i++;          j++;      }      static void two() {          System.out.println("i=" + i + " j=" + j);      }  }  

volatile实现机制:处理器为了提高处理速度,不直接和内存进行通讯,而是先将系统内存的数据读到内部缓存(L1,L2或其他)后再进行操作,但操作完之后不知道何时会写到内存,如果对声明了Volatile变量进行写操作,JVM就会向处理器发送一条Lock前缀的指令,将这个变量所在缓存行的数据写回到系统内存。但是就算写回到内存,如果其他处理器缓存的值还是旧的,再执行计算操作就会有问题,所以在多处理器下,为了保证各个处理器的缓存是一致的,就会实现缓存一致性协议,每个处理器通过嗅探在总线上传播的数据来检查自己缓存的值是不是过期了,当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置成无效状态,当处理器要对这个数据进行修改操作的时候,会强制重新从系统内存里把数据读到处理器缓存里。

0 0
原创粉丝点击