SoEZ

如果要实现线程同步,一个线程类是应该extends Thread还是implements Runnable

0
阅读(3158)
编写一个线程类,让他访问同一对象的静态资源,实现线程访问的同步
[color=#00FF00][/color]请看下面的代码:
			
				
public class Test_Sync extends Thread {
      Timer timer = new Timer();    //将Timer类设计成Test_Sync类的属性
      //重写run()方法
      public void run(){
              //Thread.currentThread().getName()得到正在执行线程的名字
               timer.add(Thread.currentThread().getName());//调用timer的add(String name)方法
          }
      
      public static void main(String[] args) {
        Test_Sync t1 = new Test_Sync();    //得到线程Test_Sync的实例t1
        Test_Sync t2 = new Test_Sync();    //得到线程Test_Sync的实例t2
        t1.setName("t1");     //设置线程的名字
        t2.setName("t2");
        t1.start();    //启动线程
        t2.start();
      }
      
    }

    class Timer{
      private static int num = 0;    //设置共享资源,请注意它的属性是static
      
      //该方法被声明为synchronized
      public synchronized void add(String name){ 
            num ++;    //每调用一次该方法num加1
            try {
                Thread.sleep(1);    //线程休眠1ms
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            System.out.println(name+", 你是第"+num+"个访问timer的线程");
      }
    }
Java code
这是上面代码的执行结果: t1, 你是第2个访问timer的线程 t2, 你是第2个访问timer的线程 显然这个结果是错误的: 如果将上面的代码作如下修改:
			
				
public class Test_Sync implements Runnable{
    public Timer t = new Timer();
    public void run(){
        t.add(Thread.currentThread().getName());
    }
    
    public static void main(String[] args){
        Test_Sync ts1 = new Test_Sync();
        Thread t1 = new Thread(ts1);
        Thread t2 = new Thread(ts1);
        t1.start();
        t2.start();
    }
}
Java code

得到正确的结果应该是: t1, 你是第1个访问timer的线程 t2, 你是第2个访问timer的线程 为什么,在第一中的实现方式中add(String name)已被声明为Synchronzied,但是很明显他并没有锁住timer对象,而如果让这个线程类实现Runnable接口而不是继承Thread,则所需的功能就可以实现。所以这个问题引发了我的思考,如果要实现线程同步,对于extends Thread 和 implements Runnable,那个更好?如果两个都可以,那他们分别使用于那些情况?

回复1:两都可以, 如果有多继承的时候 实现在接口的好, 还可以继承别的类。区别主要是继承了 Thread 不能在继承别的类了,而实现Runnable接口,还可以继承别的类和实现别的别的接口,用的时候 看具体情况

看看Thread的源代码
public class Thread implements Runnable {