当前位置: 代码迷 >> 多核软件开发 >> 与synchronized有关的线程同步有关问题
  详细解决方案

与synchronized有关的线程同步有关问题

热度:1383   发布时间:2013-02-26 00:00:00.0
与synchronized有关的线程同步问题 - Java / Java相关
package thread; 

public class SyncTest implements Runnable { 

/** 
* 深入理解多线程。 
* @param args 
*/ 
private int x; 
private int y; 
public void run(){ 
synchronized(this){ 
x++; 
y++; 

System.out.println(Thread.currentThread().getName()+",x="+x+",y="+y);//注意此打印语句不在同步块中。 

// 下面是几种输出结果 
// Thread-1,x=2,y=2  
// Thread-0,x=1,y=2 

// Thread-1,x=2,y=2 
// Thread-0,x=2,y=2 

// Thread-1,x=2,y=2 
// Thread-0,x=1,y=1 




public static void main(String[] args) { 
// TODO Auto-generated method stub 
SyncTest that=new SyncTest(); 
new Thread(that).start(); 
new Thread(that).start(); 
   



不同的对象实例的synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法; 

如果上面的二句话正确的话,现在又有了不同的疑问:被synchronized修饰的代码块能在没执行完的情况下跳出??怎么会出现第一种结果? 




------解决方案--------------------------------------------------------
我这里打印出来的结果是
Thread-0,x=1,y=1
Thread-1,x=2,y=2
但是我觉得如果不把输出语句放入同步块的话应该几种可能都有,第一个线程的输出语句和第二个进入同步块的线程在竞速
------解决方案--------------------------------------------------------
首先LZ要明白,synchronized是为了多线程对同一个共享资源同步而采取的控制措施,如果不是同一个资源,互相之间不存在任何干涉,当然就没可以同时访问了。
简单的举例,A,B两个线程,如果同时访问C,那么当A调用C的synchronized方法时,B就不能调用该方法,要等待,而如果B不去调用C,而是去掉用D的synchronized方法,因为C和D不相干,所以B当然能调用了
出现这种结果,是因为打印和累加不同步,也就是打印没在synchronized里面
简单的分析
第一个线程进入synchronized,进行x++,y++,执行后x=1,y=1,然后synchronized结束,然后进行打印,因为打印的参数是个字符串计算式,所以先求出字符串结果,Thread.currentThread().getName()+",x="+x+",y="+y,当字符串进行到+y前(注1),系统把CPU收回,分配给第二个线程(这时第一个线程停止了),然后第二个线程进入synchronized,进行x++,y++,此时x=2,y=2,然后顺利打印结束后,系统把CPU又分配给第一个线程,于是第一个线程从注1处开始继续执行+y(此时y已经是2),所以就得出输出的结果
------解决方案--------------------------------------------------------
呵呵。。稍微改变一下,LZ就都明白了。

public void run(){
synchronized(this){
x++;
y++;

System.out.println(Thread.currentThread().getName()+",x="+x+",y="+y);//注意此打印语句不在
}
}
  相关解决方案