開篇說明,有點基礎(chǔ)哟忍,知道Thread狡门,Runnable如何使用和兩者之間的關(guān)系的可以直接跳過。
先說說Thread和Runnable之間的關(guān)系锅很,簡單到不想多說一句話其馏,看下面代碼:
public class Thread implements Runnable {
...省略,詳細自行查看源代碼...
}
看到以上代碼爆安,應(yīng)該明白了吧叛复。不明白可以看一下總結(jié):Thread類實現(xiàn)Runnable接口,創(chuàng)建一個線程的時候可以使用繼承Thread的方式鹏控,但是注意Java是單繼承的致扯,當你繼承了Thread你就無法進行其它繼承了。所以当辐,可以也實現(xiàn)Runnable接口的方式抖僵,這樣就可以繼承其他類也同時可以實現(xiàn)線程創(chuàng)建。
下面先簡單介紹Thread
//使用繼承Thread的方式缘揪,創(chuàng)建一個線程類
public class OneThread extends Thread{
@Override
public void run(){
super.run();
System.out.println("one thread!!!!");
}
}
//再建一個測試類
public class TestThread {
public static void main(String[] args) {
OneThread oneThread = new OneThread();
oneThread.start();
System.out.println("完成耍群!");
}
}
注意到運行結(jié)果沒有?系統(tǒng)可能先打印“完成找筝!”蹈垢,再打印“one thread!!!!”,按照平時寫單線程來說袖裕,應(yīng)該是先打印“one thread!!!!”才對吧曹抬。不過這里是多線程,OneThread類創(chuàng)建了一個線程急鳄,這個線程里面打印“one thread!!!!”谤民,而打印“完成堰酿!”是在主線程上完成的。這也就說明了张足,使用多線程之后触创,代碼運行結(jié)果跟調(diào)用順序是無關(guān)的。(“one thread!!!!”這串字符串也有可能先出現(xiàn)为牍,反正你理解上面這話就行了)
下面在對以上兩個類進行一下改造哼绑,模擬一下cpu執(zhí)行哪個線程是具有不確定性的。
public class OneThread extends Thread{
@Override
public void run(){
try {
for (int i = 0; i < 10; i++) {
int sleepTime = (int) (Math.random()*1000);
Thread.sleep(sleepTime);
System.out.println("one thread!!!!");
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
public class TestThread {
public static void main(String[] args) {
try {
OneThread oneThread = new OneThread();
oneThread.start();
for (int i = 0; i < 10; i++) {
int sleepTime = (int) (Math.random()*1000);
Thread.sleep(sleepTime);
System.out.println("完成碉咆!");
}
} catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
使用一個隨機數(shù)抖韩,生成一個隨機的掛起時間。從而可以更好地觀察cpu選擇執(zhí)行哪個現(xiàn)場的不確定性疫铜。通俗點說一下線程開始執(zhí)行帽蝶,假如cpu選擇了主線程,然后主線程睡覺1秒鐘块攒,那么在這一秒鐘cpu可能就會選擇其它線程去執(zhí)行,而不會傻X那樣在等主線程佃乘,所以此時就會去執(zhí)行了其它線程囱井。大概這樣,不理解可以留言說一下趣避。
上面說了那么多順序的問題庞呕。反正一句話說到尾,多線程來說程帕,執(zhí)行順序是不確定的住练。還有,線程的啟動順序跟執(zhí)行start()方法的順序也沒什么關(guān)系的愁拭。start()執(zhí)行的順序不代表線程的啟動順序讲逛。在來兩段代碼爽爽唄!A氩骸盏混!繼續(xù)搗鼓那兩個類吧。惜论。许赃。懶,新建一個類都不想馆类。
public class OneThread extends Thread{
private int i;
//寫個帶參數(shù)的構(gòu)造方法混聊,主要用來看順序的
public OneThread(int i){
super();
this.i = i;
}
@Override
public void run(){
System.out.println(i);
}
}
public class TestThread {
public static void main(String[] args) {
//如各位所見,下面的start()我按順序排好的乾巧。
OneThread o1 = new OneThread(1);
OneThread o2 = new OneThread(2);
OneThread o3 = new OneThread(3);
OneThread o4 = new OneThread(4);
OneThread o5 = new OneThread(5);
OneThread o6 = new OneThread(6);
o1.start();
o2.start();
o3.start();
o4.start();
o5.start();
o6.start();
}
}
運行結(jié)果句喜,絕對不是123456预愤,如果是,那么恭喜你藤滥,運氣挺好的鳖粟。無聊話說太多了。意思基本懂吧拙绊。這些都很簡單向图,甚至有些人看了會不自覺地發(fā)出,哼一聲标沪。
Thread的簡單介紹說到這里榄攀,后面還有Runnable的簡單介紹。
通過實現(xiàn)Runnable接口來實現(xiàn)多線程金句,不廢話檩赢,先上一張圖,看看Thread類的構(gòu)造方法违寞,我們上面那些用的基本都是無參的構(gòu)造方法贞瞒,如下圖,第二個趁曼,就是我們即將要用到的構(gòu)造方法:
//創(chuàng)建一個類军浆,實現(xiàn)Runnable接口。
public class OneRunnable implements Runnable {
@Override
public void run() {
System.out.println("one runnable!!!");
}
}
public class TestThread {
public static void main(String[] args) {
//
Runnable runnable = new OneRunnable();
//這里就是用到了上圖的第二個構(gòu)造方法挡闰,不用多說吧乒融,就這樣
Thread thread = new Thread(runnable);
thread.start();
System.out.println("完成");
}
}
直接實現(xiàn)Runnable接口這樣解決了Java單繼承這一尷尬!I忝酢T藜尽!
后面應(yīng)該先簡單一起學(xué)習(xí)下共享數(shù)據(jù)和Thread的幾個方法奢驯。
向大家推薦eclipse的vim插件申钩,太好用了。
這里不是廣告叨橱,推薦本書《Java多線程核心技術(shù)》-高洪巖典蜕,因為我是看著這本書學(xué)習(xí)的。上面的文章是學(xué)習(xí)筆記罗洗,并不是用來說教的愉舔,不要錯了點什么就噴我。