采用繼承Thead類實現多線程:
優勢:編寫簡單,如果需要訪問當前線程,只需使用this即可,無需使用Thead.currentThread()方法。
劣勢:因為這種線程類已經繼承了Thead類,所以不能再繼承其它類。
示例代碼:
package org.frzh.thread;
public class FirstThread extends Thread{
private int i;
//重寫run方法,run方法的方法體就是線程執行體
public void run() {
for (; i < 100; i++) {
//當線程類繼承Thread類時,可以直接調用getName方法獲得當前線程名
//如果想獲得當前線程,直接使用this
//Thread對象的getName方法返回當前線程的名字
System.out.println(getName() + " " + i);
}
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
//調用Thead的currentThread方法獲取當前線程
System.out.println(Thread.currentThread().getName() + " " +i);
if (i == 20) {
new FirstThread().start();
new FirstThread().start();
}
}
}
}
運行結果片段:
我們發現,在兩個子線程中i的值并不連續,似乎與我們說的子線程直接共享數據不符。其實,在這里我們實例化了兩個子線程,每個擁有自己的實例變量i。
采用實現Runable接口的多線程:
優勢:線程類只是實現了Runable接口,因此還可以繼承其他類;
在這種情況下,可以使多個線程共享一個target對象,所以非常適合多個線程用來處理同一份資源的情況,從而可以將cpu、代碼和數據分開,形成清晰的模型,較好的體現面向對象思想。
劣勢:編程略有些復雜,如果要訪問當前線程必須使用Thread.currentThread方法。
示例代碼:
package org.frzh.thread;
public class SecondThread implements Runnable{
private int i;
@Override
public void run() {
// TODO Auto-generated method stub
for (; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
if (i == 20) {
SecondThread st = new SecondThread();
new Thread(st, "子線程1").start();
new Thread(st, "子線程2").start();
}
}
}
}
運行結果片段:
可以看到,此時的i值是連續變化的,因為線程1和2共享同一個target。