当前位置: 代码迷 >> J2SE >> 关于线程同步的代码简单小例子,过了一年,还是有关问题
  详细解决方案

关于线程同步的代码简单小例子,过了一年,还是有关问题

热度:206   发布时间:2016-04-24 18:02:41.0
关于线程同步的代码简单小例子,过了一年,还是问题。
Java code
public class ViolentAccessDemo {   public static void main(String[] args) {      ViolentObject violentObject = new ViolentObject();      Thread thread1 = new Thread(new ThreadAccess(violentObject));      Thread thread2 = new Thread(new ThreadAccess(violentObject));      thread1.start();      thread2.start();      for(int i=0;i<10;i++){         violentObject.print();         try{            Thread.sleep(500);                     }catch(InterruptedException e){}      }   }}class ViolentObject{   private int x;   private int y;   private int z;   private int a;   public void increase(){  //这里输出的值是不一样,因为            //x++ 在刚被执行完之后,就退出时间片,而下次进来的线程又重新执行x++。           //那么肯定地说x的值加到最后,必然是最大的。可是事实上,并不是如此。            //加最一个synchronized是不是保证这句代码被执行完解锁,再退出CPU时间片。           //很不解。      x++;      y++;      z++;      a++;   }   public void print(){      System.out.println("x="+x+",y="+y+",z="+z+",a="+a);   }}class ThreadAccess implements Runnable{   private ViolentObject violentObject;   public ThreadAccess(ViolentObject violentObject){      this.violentObject = violentObject;   }   public void run(){      while(true) violentObject.increase();   }}


------解决方案--------------------
//这里输出的值是不一样,因为
//x++ 在刚被执行完之后,就退出时间片,而下次进来的线程又重新执行x++。
//那么肯定地说x的值加到最后,必然是最大的。可是事实上,并不是如此。
//加最一个synchronized是不是保证这句代码被执行完解锁,再退出CPU时间片。
//很不解。

你可以在x++ 后面加个
try{
Thread.sleep(50);
}catch(InterruptedException e){}
这样就可以更好的让一个时间片到期。
看看,这样效果就出来了,显示x的值最大。
------解决方案--------------------
我打出来的结果的确是x最大啊,楼主你的什么结果?
------解决方案--------------------
看不到有什么线程同步和控制的代码呀。

而且
public void increase()
这里没有同步标识,你们的不是一个atomic的调用,当然有问题。完全是听天由命式的多线程并发处理。
------解决方案--------------------
如果楼主只是想要看到x的值最大的话,可以在x++之后睡眠,这样另一个线程就有机会得到时间片执行

对于加上synchronized,只能保证synchronized的方法一次执行完后释放锁,但不能保证别的方法比如说你这里的public void print()不能访问其中的x,y,z和a,所以看不出来x的值最大
------解决方案--------------------
问题可能出在print这里,因为没有同步所以print取得的数据也是在变化的

你拿每一个数字的时候,他们都在增长啊
------解决方案--------------------
探讨
每个线程拿到的时间片均是重新开始执行。
x++ y++ z++ a++
顺序过来,是吗?
还是记着我上次执行了x++,再执行y++???


------解决方案--------------------
如果你想把线程理解透的话最好看看操作系统。
------解决方案--------------------
抢用资源的造成的不同步:

x=0 y=0 z=0 a=0
线程A:拿到x=0
线程A:自增,x=1

线程B:拿到x=0
线程B:自增,x=1

线程A:写回x=1
线程B:写回x=1
------解决方案--------------------
改下,这种可能性比较大……

线程A:拿到x=0

线程B:拿到x=0
线程B:自增,x=1
线程B:写回x=1

线程A:自增,x=1
线程A:写回x=1

------解决方案--------------------
还是没说清楚,假设修改可以立即返回……

线程A:拿到x=0

线程B:拿到x=0
线程B:自增,x=1

线程A:自增,x=1
------解决方案--------------------
x++;
执行过程如下:
Java code
1    ALOAD 02    DUP3    GETFIELD ViolentObject.x : I4    ICONST_15    IADD6    PUTFIELD ViolentObject.x : I
------解决方案--------------------
  相关解决方案