日期:2014-05-20  浏览次数:20718 次

synchronized线程同步的问题
这个程序是多线程的程序吗~ 为什么使用synchronized之后 运行的会是main线程在不断的执行呢~
如果将main线程sleep一下~就会是run一直不断的运行~为什么他们不会同步的交替的运行~
如何能让一个线程 释放锁旗标 呢~


如果要实现同步的交替运行那么该怎么修改呢~public class ThreadTest 
{
  public static void main(String[] args)
{
RunTest rt =new RunTest();
rt.start();
// 这里让main线程sleep一下~再运行就会出现run线程不断执行的情况~
// try {Thread.sleep(1);}catch (Exception e){e.printStackTrace();}
rt.see();
}
}

class RunTest extends Thread
{
public void run()
{
synchronized(this)
{
while(true)
{
System.out.println("2222222"+Thread.currentThread().getName());
}
}
}
public void see()
{
synchronized(this)
{
while(true)
{
System.out.println("1111111111"+Thread.currentThread().getName());
}
}
}
}

------解决方案--------------------
synchonized的本意是让多个线程交替执行同一个方法(即执行同一段synchronized代码),你现在是两个线程分别执行两个方法,也就是两个线程分别执行两段synchronized代码,这样的synchronized没有实际的意义。之所以出现某个线程不断执行,并不是synchronized放锁不放锁的问题,只是cpu被循环占用的问题,所以只要你在循环中sleep一下或者yield一下就可以了。synchronized在你这个例子中可以去掉不要,你要也不影响结果
在System.out.println( "2222222 "+Thread.currentThread().getName()); 和System.out.println( "1111111111 "+Thread.currentThread().getName()); 两条语句之后都加入yield();或者加入sleep(100);


------解决方案--------------------
我觉得4楼阿宝兄的解释不太准确。

首先,synchonized本意并不只是“让多个线程交替执行同一个方法”,而是要在一个标志(就是同步对象,本例中的this,也就是一开始new出来的那个RunTest对象)的控制之下,多个线程只能有一个获得执行权。

而本例中没有达到LZ预期的效果,也不是“cpu被循环占用的问题”,而是synchonized的用法不对。

LZ的代码虽然在两个线程中都用了synchronized,但由于循环工作是在synchronized块内进行的,那么,一旦一个线程获得了执行权,它就开始循环执行,再也不让出标志对象,于是另一个线程就永远无法进入synchronized块内了。

正确的做法应该是把synchronized放在while循环的内部,每循环一次,就synchronized一次。

不过,即使这样,也不能实现严格意义上的“交替执行”,这种做法只能是给每个线程提供平等的机会得到执行权。要想实现严格的“交替执行”,仅靠synchronized进行同步是不够的,还要有其它的控制手段。