通过Runnable与Thread实现多线程的区别
先po出以下两段网上都有的类似的代码
Runnable
public class Runnable1 implements Runnable {
private int tickets=20;
private ReentrantLock lock=new ReentrantLock();
public void run(){
for(;tickets>0;) {
lock.lock();
System.out.println(Thread.currentThread().getName() + String.format(":%d",tickets));
tickets--;
lock.unlock();
try {
Thread.sleep(1000);
}catch (InterruptedException e){}
}
}
}
public static void main(String[] arg ){
//Runnable implementation test
Runnable1 runnable1=new Runnable1();
new Thread(runnable1).start();
new Thread(runnable1).start();
new Thread(runnable1).start();
}
OutPut:
Thread-0:20
Thread-2:19
Thread-1:18
Thread-0:17
Thread-2:16
Thread-1:15
Thread-0:14
Thread-1:13
Thread-2:12
Thread-0:11
Thread-1:10
Thread-2:9
Thread-0:8
Thread-1:7
Thread-2:6
Thread-0:5
Thread-1:4
Thread-2:3
Thread-0:2
Thread-1:1
Thread
public class Thread1 extends Thread {
private int tickets=5;
private ReentrantLock lock=new ReentrantLock();
@Override
public void run(){
for(;tickets>0;) {
lock.lock();
System.out.println(Thread.currentThread().getName() + String.format(":%d", tickets));
tickets--;
lock.unlock();
try {
Thread.sleep(500);
}catch (InterruptedException e){}
}
}
}
public static void main(String[] arg ){
//Thread subclasss test
//Thread1 thread1=new Thread1();
new Thread1().start();
new Thread1().start();
new Thread1().start();
}
Output:
Thread-2:5
Thread-0:5
Thread-1:5
Thread-1:4
Thread-0:4
Thread-2:4
Thread-0:3
Thread-1:3
Thread-2:3
Thread-1:2
Thread-0:2
Thread-2:2
Thread-0:1
Thread-1:1
Thread-2:1
Explain
看了下Thread的构造函数
通过Runnable进行构造
public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0); }
空参构造
public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0); }
发现最后调用的都是init()函数,而该函数又是调用以下init()函数,acc参数为null
/**
* Initializes a Thread.
*
* @param g the Thread group
* @param target the object whose run() method gets called
* @param name the name of the new Thread
* @param stackSize the desired stack size for the new thread, or
* zero to indicate that this parameter is to be ignored.
* @param acc the AccessControlContext to inherit, or
* AccessController.getContext() if null
*/
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc)
不难看出,Runnable类型参数的作用是 the object whose run() method gets called ,亦即提供run() 方法。所以,用同一个Runnable去实例化多个Thread,提供的run()方法是一个主体,因而能有共享参数的效果。
然而,通过无参方式进行初始化,每次初始化都是由一个新的Thread1实例,它们之间的run()函数除了同名,没有任何瓜葛。所以不可能会共享参数。