線程與進程
進程:是指一個內存中運行的應用程序,每個進程都有一個獨立的內存空間.
線程:是進程中的一個執行路徑,共享一個內存空間,線程之間可以自由切換,并發執行. 一個進程最少 有一個線程. 線程實際上是在進程基礎之上的進一步劃分,一個進程啟動之后,里面的若干執行路徑又可以劃分 成若干個線程.
為什么使用線程:1.在開發軟件的時候提高流暢度
2.用戶體驗和客戶需求等
線程調度
分時調度:所有線程輪流使用 CPU 的使用權,平均分配每個線程占用 CPU 的時間。
搶占式調度:優先讓優先級高的線程使用 CPU,如果線程的優先級相同,那么會隨機選擇一個(線程隨機性),
Java使用的為搶占式調度。
CPU使用搶占式調度模式在多個線程間進行著高速的切換。對于CPU的一個核新而言,某個時刻,
只能執行一個線程,而 CPU的在多個線程間切換速度相對我們的感覺要快,看上去就是 在同一時
刻運行。 其實,多線程程序并不能提高程序的運行速度,但能夠提高程序運行效率,讓CPU的 使
用率更高。
線程的創建和使用
Java語言的JVM允許程序運行多個線程,它通過java.lang.Thread類來體現。
Thread類的特性
每個線程都是通過某個特定Thread對象的run()方法來完成操作的,經常把run()方法的主體稱為線程體
通過該Thread對象的start()方法來啟動這個線程,而非直接調用run().
Runnable 與 Callable:
接口定義
//Callable接口
public interface Callable<V> {
V call() throws Exception;
}
//Runnable接口
public interface Runnable {
public abstract void run();
}
Callable使用步驟
1. 編寫類實現Callable接口 , 實現call方法
class XXX implements Callable<T> {
@Override
public <T> call() throws Exception {
return T;
}
}
2. 創建FutureTask對象 , 并傳入第一步編寫的Callable類對象
FutureTask<Integer> future = new FutureTask<>(callable);
3. 通過Thread,啟動線程
new Thread(future).start();
Runnable 與 Callable的相同點
都是接口
都可以編寫多線程程序
都采用Thread.start()啟動線程
Runnable 與 Callable的不同點
Runnable沒有返回值;Callable可以返回執行結果
Callable接口的call()允許拋出異常;Runnable的run()不能拋出
Callable獲取返回值
Callalble接口支持返回執行結果,需要調用FutureTask.get()得到,此方法會阻塞主進程的繼續往下執行,如果不調用不會阻塞。
以下為多線程售票的問題:
package com;
import javax.imageio.stream.ImageInputStream;
public class Demo02 {
public static void main(String[] args) {
Runnable run = new Ticket();
new Thread(run).start(); //建立多線程
new Thread(run).start();
new Thread(run).start();
}
public static class Ticket implements Runnable{
private int count = 10; // 總的票數,這個是共享資源,多個線程都會訪問
@Override
public void run() {
while (true) {// 循環是指線程不停的去賣票,直到票賣完為止
synchronized(this){ // 當操作的是共享數據時,
// 用同步代碼塊進行包圍起來,執行里面的代碼需要mutex的鎖,但是mutex只有一個鎖。這樣在執行時,只能有一個線程執行同步代碼塊里面的內容
if (count > 0) {
System.out.println("正在準備售票!");
count--;
System.out.println(Thread.currentThread().getName()+"出票成功,余票:" + count); //獲取線程的名字
}try {
Thread.sleep(1000);
/**
* sleep不釋放鎖,其他線程拿不到鎖,也不能執行同步代碼。
* 所以把睡覺放到同步代碼塊的外面,這樣賣完一張票就睡一會,讓其他線程再賣,這樣所有的線程都可以賣票
*/
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}

浙公網安備 33010602011771號