java多线程基础二


本章主要说明 synchronized 和 volatile关键字的理解。


先看一段代码

public class ThreadVolatileDemo {
 public static int i = 0;
 public static void addI(){
   i++;
 }
 
 public static void main(String[] args) {
  
  for(int j = 0;j<1000;j++){
   Thread t = new Thread(){
    public void run(){
     ThreadVolatileDemo.addI();
    }
   };
   t.start();
  }
  try {

//这里睡一秒主要是为了启动的1000个线程执行完成,然后再打印出i的值
   Thread.sleep(1000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  System.out.println("i: "+i);
 }
}


看打印结果:998

可以多执行几次,执行结果都不一样,并不是我们想要的结果1000,

如果加上volatile 关键字结果会不会就是1000呢,因为volatile关键字的作用就是在线程要使用i的值的时候,都会从主内存中取最新的值,然后加载到本地线程内存中。

public static volatile int i = 0;

加上volatile 关键字 打印结果:999  结果依旧不是想要的结果1000.

每一个线程运行时都有一个线程栈,线程栈保存了线程运行时候变量值信息。当线程访问某一个对象时候值的时候,首先通过对象的引用找到对应在堆内存的变量的值,然后把堆内存

变量的具体值load到线程本地内存中,建立一个变量副本,之后线程就不再和对象在堆内存变量值有任何关系,而是直接修改副本变量的值,

在修改完之后的某一个时刻(线程退出之前),自动把线程变量副本的值回写到对象在堆中变量。这样在堆中的对象的值就产生变化了。

对于volatile修饰的变量,jvm虚拟机只是保证从主内存加载到线程工作内存的值是最新的

假如线程1,线程2 在进行加载主内存中的i操作中,发现主内存中i的值都是10,那么都会加载这个最新的值

那么线程1和线程2 在更新主内存中的i的值都是11



如果要想得到我们想要的值1000,我们可以加上synchronized关键字

完整代码如下:

public class ThreadVolatileDemo {
 public static int i = 0;
 public static Object obj = new Object();
 public static void addI(){
  synchronized(obj){
   i++;
  }
 }
 public static void main(String[] args) {
  for(int j = 0;j<1000;j++){
   Thread t = new Thread(){
    public void run(){
     ThreadVolatileDemo.addI();
    }
   };
   t.start();
  }
  try {
   Thread.sleep(1000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  System.out.println("i: "+i);
 }
}


这样不管执行多少次结果都是1000.

在执行 i++; 由于对obj对象加上锁(synchronized),例如线程1 拿到obj的锁 对i进行操作,线程2就只能等 线程1操作结束后释放obj的锁,

然后线程2拿到obj的锁,此时其他线程也都是不能对i进行操作的。


对synchronized关键字可以

修饰代码块

修饰方法

修饰静态方法

修饰类

A. 无论synchronized关键字加在方法上还是对象上,如果它作用的对象是非静态的,则它取得的锁是对象;如果synchronized作用的对象是一个静态方法或一个类,则它取得的锁是对类,该类所有的对象同一把锁。
B. 每个对象只有一个锁(lock)与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码。
C. 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。


关于synchronized关键字推荐博客链接:http://blog.csdn.net/luoweifu/article/details/46613015















;