1 继承Thread类,重写run方法。Thread类实现了Runnable接口。
2 实现Runnable接口,重写run方法。相比于继承Thread类,可以避免单继承的缺陷和实现资源共享。
举例:假设两个窗口在卖5张火车票。
继承Thread类方式:
1 public class SharedDataThreadDemo {
2 public static void main(String[] args) {
3 TicketThread t1 = new TicketThread("1号窗口");
4 t1.start();
5
6 TicketThread t2 = new TicketThread("2号窗口");
7 t2.start();
8 }
9 }
10
11 class TicketThread extends Thread {
12 private int ticket = 5;
13
14 public TicketThread(String name) {
15 super(name);
16 }
17
18 @Override
19 public void run() {
20 while(true) {
21 System.out.println(this.getName() + ":" + (ticket--));
22 if(ticket < 1) {
23 break;
24 }
25 }
26 }
27 }
结果如下:
1 1号窗口:5
2 2号窗口:5
3 1号窗口:4
4 2号窗口:4
5 1号窗口:3
6 2号窗口:3
7 1号窗口:2
8 2号窗口:2
9 1号窗口:1
10 2号窗口:1
每个线程相互独立,不共享资源,每个线程各自卖了5张票,总共卖出10张票。如果真卖票,就有问题了。
实现Runnable接口方式:
1 public class SharedDataThreadDemo {
2 public static void main(String[] args) {
3 TicketRunnable ticketRunnable = new TicketRunnable();
4 Thread t1 = new Thread(ticketRunnable, "1号窗口");
5 t1.start();
6
7 Thread t2 = new Thread(ticketRunnable, "2号窗口");
8 t2.start();
9 }
10 }
11
12 class TicketRunnable implements Runnable {
13 private int ticket = 5;
14
15 @Override
16 public void run() {
17 while(true) {
18 System.out.println(Thread.currentThread().getName() + ":" + (ticket--));
19 if(ticket < 1) {
20 break;
21 }
22 }
23 }
24
25 }
结果如下:
2号窗口:4
1号窗口:5
2号窗口:3
1号窗口:2
2号窗口:1
每个线程共享了实现Runnable接口的类实例资源即对象ticketRunnable的火车票资源,共卖出10张票。
3 实现Callable接口,重写call方法,有返回值。
4 使用实现了Executor接口的ThreadPoolExecutor来创建线程池。
参考资料