如果要实现线程同步,一个线程类是应该extends Thread还是implements Runnable
0赞
发表于 9/11/2012 9:18:18 AM
阅读(3158)
编写一个线程类,让他访问同一对象的静态资源,实现线程访问的同步
[color=#00FF00][/color]请看下面的代码:
[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
-
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 {
