深入探析Java线程锁机制

深入探析Java线程锁机制

  今天在iteye上提了一个关于++操作和线程安全的问题,一位朋友的回答一言点醒梦中人,至此我对Java线程锁有了更加深刻的认识。在这里也做个总结供大家参考 托福代考 托福答案

  先看几段代码吧!

  代码一:

  [java]

  public class TestMultiThread2 implements Runnable{

  private static Object o = new Object();

  private static Integer si = 0;

  private static AtomicInteger flag = new AtomicInteger();

  @Override

  public void run() {

  for(int k=0;k<2000000;k++){

  synchronized(si){

  si++;

  }

  }

  flag.incrementAndGet();

  }

  public static void main(String[] args) throws InterruptedException{

  TestMultiThread2 t1 = new TestMultiThread2();

  TestMultiThread2 t2 = new TestMultiThread2();

  ExecutorService exec1 = Executors.newCachedThreadPool();

  ExecutorService exec2 = Executors.newCachedThreadPool();

  exec1.execute(t1);

  exec2.execute(t2);

  while(true){

  if(flag.intValue()==2){

  System.out.println("si>>>>>"+si);

  break;

  }

  Thread.sleep(50);

  }

  }

  }

  为了方便看,重复的就不插入了,从代码二到代码四只插入run()方法中的代码,其他地方都一样

  代码二:

  [java]

  public void run() {

  for(int k=0;k<2000000;k++){

  synchronized(o){

  si++;

  }

  }

  flag.incrementAndGet();

  }

  代码三:

  [java]

  public void run() {

  for(int k=0;k<2000000;k++){

  synchronized(o){

  si++;

  o = new Object();

  }

  }

  flag.incrementAndGet();

  }

  代码四:

  [java]

  public void run() {

  for(int k=0;k<2000000;k++){

  synchronized(o){

  si++;

  Object temp = o;

  o = new Object();

  o = temp;

  }

  }

  flag.incrementAndGet();

  }   有了这四段代码我想问题大概可以说明白了,这里说一下输出吧。

  代码一:<4000000

  代码二:=4000000

  代码三:<4000000

  代码四:<4000000(PS:这个结果非常接近4000000)

  这里说明一下我测试中碰到的问题,代码四一直没有跑出我想要的结果,主要是开始我设的循环次数太少,其实这里如果要这个现象更加明显一些可以在中间多new 几个Object 如下面的代码五,这样现象就比较明显了雅思代考 雅思答案

  代码五:

  [java]

  public void run() {

  for(int k=0;k<2000000;k++){

  synchronized(o){

  si++;

  Object temp = o;

  for(int m=0;m<10;m++){

  o = new Object();

  }

  o = temp;

  }

  }

  flag.incrementAndGet();

  }

  为什么会出现上面的现象:

  代码一:当si做++操作后(可以直接看字节码,这里不贴了)在putstatic之前有几步操作,就是我们常说的非原子操作,而这时候si已经不是原来的对象了,这样锁对另外一个线程来说就失效了,我想代码三和代码四就是最好的佐证,代码四更有说服力。当时因为没有出现预想的情况困惑了挺久职称英语代考 职称英语答案

  其实这里用字节码来解释还不是很严谨,最好的当然直接是汇编代码

  如有什么问题还希望各位读者指正。

你可能感兴趣的:(深入探析Java线程锁机制)