Thread和Runnable的区别
如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。
main函数,实例化线程对象也有所不同,
- extends Thread :t.start();
- implements Runnable : new Thread(t).start();
总结:
实现implements Runnable接口比继承 extends Thread类所具有的优势:
- 1):适合多个相同的程序代码的线程去处理同一个资源。
- 2):可以避免java中的单继承的限制(不能访问父类的私有成员?)。
- 3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。
- 4):线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread的类。
为什么这么说类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享:举个卖票的例子:
继承Thread类的方法
package multithreading;
public class MyThreadWithExtends extends Thread {
private int tickets = 10;
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
if(tickets>0){
System.out.println(Thread.currentThread().getName()+"--卖出票:" + tickets--);
}
}
}
public static void main(String[] args) {
MyThreadWithExtends thread1 = new MyThreadWithExtends();
MyThreadWithExtends thread2 = new MyThreadWithExtends();
MyThreadWithExtends thread3 = new MyThreadWithExtends();
thread1.start();
thread2.start();
thread3.start();
//每个线程都独立,不共享资源,每个线程都卖出了10张票,总共卖出了30张。如果真卖票,就有问题了。
}
}
运行结果:
Thread-0--卖出票:10;Thread-2--卖出票:10;Thread-1--卖出票:10;Thread-2--卖出票:9
Thread-0--卖出票:9;Thread-2--卖出票:8;Thread-1--卖出票:9;Thread-2--卖出票:7
Thread-0--卖出票:8;Thread-2--卖出票:6;Thread-2--卖出票:5;Thread-2--卖出票:4
Thread-1--卖出票:8;Thread-2--卖出票:3;Thread-0--卖出票:7;Thread-2--卖出票:2。。。。。。
每个线程都独立,不共享资源,每个线程都卖出了10张票,总共卖出了30张。如果真卖票,就有问题了。
实现Runnable接口方式
package multithreading;
public class MyThreadWithImplements implements Runnable {
private int tickets = 10;
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
if(tickets>0){
System.out.println(Thread.currentThread().getName()+"--卖出票:" + tickets--);
}
}
}
public static void main(String[] args) {
MyThreadWithImplements myRunnable = new MyThreadWithImplements();
Thread thread1 = new Thread(myRunnable, "窗口一");
Thread thread2 = new Thread(myRunnable, "窗口二");
Thread thread3 = new Thread(myRunnable, "窗口三");
thread1.start();
thread2.start();
thread3.start();
}
}
运行结果:
窗口二--卖出票:10
窗口三--卖出票:9
窗口一--卖出票:8
窗口三--卖出票:6
窗口三--卖出票:4
窗口三--卖出票:3
窗口三--卖出票:2
窗口三--卖出票:1
窗口二--卖出票:7
窗口一--卖出票:5
使用了同一个Runnable接口,每个线程共享了对象myRunnable的资源。
Thread负责线程本身相关的职责和控制,而Runnable则负责逻辑执行单元的部分。
卖出的总票数是对的,但是顺序是乱的,怎么办?