一、实现方法
1、继承Thread类
2、实现Runnable接口
(一)继承Thread类
对于直接继承Thread的类来说,代码大致框架是:
class 类名 extends Thread{ 方法1; 方法2; … public void run(){ // other code… } 属性1; 属性2; … }
先看一个错误的例子:
1 /** 2 * 继承Thread类,直接调用run方法 3 */ 4 class hello extends Thread { 5 private String name; 6 7 public hello() { 8 } 9 10 public hello(String name) { 11 this.name = name; 12 } 13 14 public void run() { 15 for (int i = 0; i < 5; i++) { 16 System.out.println(name + "运行 " + i); 17 } 18 } 19 20 public static void main(String[] args) { 21 hello h1 = new hello("A"); 22 hello h2 = new hello("B"); 23 h1.run(); 24 h2.run(); 25 } 26 }
我们会发现这些都是顺序执行的,说明我们的调用方法不对,应该调用的是start()方法。
将main函数改为以下代码
public static void main(String[] args) { hello h1 = new hello("A"); hello h2 = new hello("B"); h1.start(); h2.start(); }
运行的结果可能为:
A运行 0
B运行 0
A运行 1
B运行 1
A运行 2
B运行 2
A运行 3
A运行 4
B运行 3
B运行 4
因为需要用到CPU的资源,所以每次的运行结果基本是都不一样的。
注意:虽然我们在这里调用的是start()方法,但是实际上调用的还是run()方法的主体。
那么:为什么我们不能直接调用run()方法呢?
我的理解是:线程的运行需要本地操作系统的支持。
(二)实现Runnable接口
代码大致框架如下:
class 类名 implements Runnable{ 方法1; 方法2; … public void run(){ // other code… } 属性1; 属性2; … }
先看个例子(注意和继承Thread ,main函数的不同):
1 /** 2 * 调用Runnable方法 3 */ 4 class hello implements Runnable { 5 private String name; 6 7 public hello() { 8 } 9 10 public hello(String name) { 11 this.name = name; 12 } 13 14 public void run() { 15 for (int i = 0; i < 5; i++) { 16 System.out.println(name + "运行 " + i); 17 } 18 } 19 20 public static void main(String[] args) { 21 hello h1 = new hello("A"); 22 Thread t1 = new Thread(h1); 23 hello h2 = new hello("B"); 24 Thread t2 = new Thread(h2); 25 t1.start(); 26 t2.start(); 27 } 28 }
可能的运行结果为:
A运行 0
B运行 0
B运行 1
B运行 2
B运行 3
B运行 4
A运行 1
A运行 2
A运行 3
A运行 4
Thread和Runnable的区别:
如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。
总结一下:
实现Runnable接口比继承Thread类所具有的优势:
1)适合多个相同的程序代码的线程去处理同一个资源
2)可以避免java中的单继承的限制
3)增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。
所以,本人建议大家尽量实现接口。
时间: 2024-11-07 19:20:27