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

初学线程遇到个问题,求解答。。
一直在看马士兵的java视频教程,今天学到线程这一章,跟着编了个程序。
注释符号以后的是他的定义方法,我自己用了另一种方法,
Thread t1 = new Thread(new TestSync1());
最后输出的结果:
t1你是第2个
 t2你是第2个
我感觉我的这个定义方法应该是相当于
TestSync1 test1 = new TestSync1();
TestSync1 test2 = new TestSync1();
Thread t1 = new Thread(test1);
Thread t2 = new Thread(test2);
不知道这样为什么会输出错误,希望有大神来解答。。
public class TestSync1 implements Runnable{
  Time timer = new Time();
  public static void main(String args[]){
  // TestSync1 test = new TestSync1();
  // Thread t1 = new Thread(test);
  // Thread t2 = new Thread(test);
 
  Thread t1 = new Thread(new TestSync1());
  Thread t2 = new Thread(new TestSync1());
  t1.setName("t1");
  t2.setName("t2");
  t1.start();
  t2.start();
 
  }
  public void run(){
  timer.add(Thread.currentThread().getName());
  }
 
 }
 class Time{
  private static int num = 0;
  public synchronized void add(String name){
 
  num++;
  try{
  Thread.sleep(1);
  }catch(InterruptedException e){ }
  System.out.println(name+"你是第"+num+"个");
  }
 
 }
 
------最佳解决方案--------------------
Thread t1 = new Thread(new Test());
Thread t2 = new Thread(new Test());
你的这种方式会导致t1和t2线程执行add方法所获取的锁不同,因此add方法就不再具有互斥的作用,两个线程并发执行,num++不是原子操作,它分为加载,自增和写入三个步骤,所以运行的结果是不确定的,打印出来的结果有可能是1,2 有可能是2,2

而 Test test = new Test();
  Thread t1 = new Thread(test);
  Thread t2 = new Thread(test);
这种写法保证了两个线程访问的是同一个对象的add方法,synchronized锁写起到了作用
------其他解决方案--------------------
楼主的代码产生2个TestSync1 对象,每个对象里面有各自的Time对象,象1楼所说,同步失去作用了。
按照楼主的饿代码,门楼住可以把 timer定义成静态的看看效果。
------其他解决方案--------------------
楼上说的都对

------其他解决方案--------------------
差不多知道了,感谢。