一、進程與多線程的概念及線程的優點
進程:操作系統的基本運行單元,是程序的一次執行。
線程:在進程中獨立運行的子任務。
Eg:QQ是一個進程,則好友視頻,下載文件,數據傳輸等都是線程。
單任務:排隊執行,一個時間就一個線程執行,也就是同步。
多任務:一個時間有多個線程同時執行,也就是異步。
二、多線程講解
1.線程的創建
一種是繼承Thread類,,另一種是實現Runnable接口。兩種方法沒有本質的區別,因爲Thread類在底層也是實現了Runnable接口,
但是繼承Thread類的方法不支持多繼承。
先是Thread方法:
<span style="font-family:KaiTi_GB2312;font-size:14px;">public class MyThread extends Thread {
@Override
public void run () {
super.run();
System.out.println("MyThread");
}
}
public class RunTest() {
public static void main(String [] args) {
MyThread thread = new MyThread();
thread.start();
System.out.println("main運行結束");
}
}</span>
上面是基本的創建以及線程調用的方法(Start())。
運行的結果是
MyThread
main運行結束
或者順序倒過來,都有可能,因爲在多線程中,代碼的運行結果和代碼的執行順序是無關的。
2.Runnable的使用
<span style="font-family:KaiTi_GB2312;font-size:14px;">public class MyRunnable implements Runnable {
@Override
public void run () {
super.run();
System.out.println("Runnable");
}
}
public class RunTest() {
public static void main(String [] args) {
Runnable run = new MyRunnable();
Thread thread = new Thread(run);
thread.start();
System.out.println("main運行結束");
}
}
</span>
這裏看到Thread類在創建時傳遞了一個實現了Runnable的實例參數,,這就是Runnable的使用方式
在Thread類中,常用的幾個構造方法有:
Thread()
Thread(Runnable target)
Thread(Runnable target,String name)
這裏有一個概念是
非線程安全:主要是指對個線程對同一個對象中的同一個實例變量進行操作時,會出現的值被更改,值不同步的情況,進而影響程序的執行流程
Eg: 大象裝冰箱的操作,分三步,打開冰箱門,裝進去,關上。但是要是多線程,在你打開之後另一個線程給你關了,大象裝哪?這就產生了非線程安全。
解決的辦法是:在run方法前加上synchronized關鍵字,這樣run方法的執行實際上是排隊執行的。
synchronized 可以對任意對象和方法加鎖,而加鎖的這段代碼稱爲“互斥區或臨界區”。
三、多線程中的方法
1.線程啓動 :start(),重新創建一個線程,並執行run方法。
如果在main中寫MyThread.run(),則只能是當做普通的函數調用一樣,和多線程沒有什麼關係。
2.currentThread()方法返回代碼正在被哪個線程調用的信息。currentThread().getName();
3.isAlive()是否處於活動狀態
4.getId()返回線程的唯一標識
5.停止線程 :可以用stop(). 但是這個是線程不安全的 。
因爲強行停止的話一些清理工作可能還來不及處理,還有一個問題就是對鎖定的對象進行了解鎖,導致數據得不到同步處理,出現不一致的問題。
所以這種方法現在以及不要
推薦用interrupt(),這個方法不會終止一個正在運行的線程,而是會加入一些判斷才停止。
6.interrupted():測試當前線程是否已經中斷。
7、暫停和恢復:suspend()和resume()也會導致數據不同步問題,所以也不用了。
8.yield():放棄當前CPU資源,但是放棄的時間不確定。
9.設置優先級:setProperty().線程優先級有10個,1-10,可設置。
注意:線程的優先級具有繼承性。
即:A線程啓動B線程,則B線程的優先級和A一樣。