多執行緒基礎(一)
最近讀了高洪巖的《Java多執行緒程式設計核心技術》一書,打算記錄下多執行緒的基礎知識點,也算對本書的一個讀後感了。目前打算分四五篇博文進行記錄。
第一篇主要是記錄執行緒的概念,建立,常用的基礎方法等。
1. 什麼是執行緒?
通常我們所說執行緒是程序的最小單位。那麼問題來了,什麼是程序呢?程序就是作業系統結構的基礎;是一次程式的執行;等等,他是系統進行資源分配和排程的一個獨立單位。
2. 建立執行緒的4種方式
1、繼承Thread類 2、實現Runnable介面 3、實現Callable介面重寫call()方法(注:需要搭配Future) 4、使用執行緒池(例:Executor框架)
3. 下面講解執行緒中的各方法使用
3.1 currentThread()方法
作用:返回程式碼段正在被哪個執行緒呼叫的資訊。
示例:
public class CreateThreandA implements Callable { @Override public Object call() throws Exception { System.out.println("run方法:"+Thread.currentThread().getName()); return "ok"; } public static void main(String[] args) throws ExecutionException, InterruptedException { CreateThreandA threandA = new CreateThreandA(); FutureTask futureTask = new FutureTask(threandA); ExecutorService executorService = Executors.newFixedThreadPool(1); executorService.submit(futureTask); executorService.shutdown(); System.out.println("mian方法:"+Thread.currentThread().getName()); } } //執行結果 mian方法:main run方法:pool-1-thread-1
3.2 isAlive()方法
作用:判斷當前執行緒是否處於活動狀態(true活動狀態、false執行緒終止)
示例:
public class CreateThreandA extends Thread { @Override public void run() { System.out.println("begain···"); System.out.println("threandA="+this.isAlive()); System.out.println("end···"); } public static void main(String[] args) throws InterruptedException { CreateThreandA threandA = new CreateThreandA(); threandA.start(); threandA.join(); System.out.println("threandA="+threandA.isAlive()); } } //執行結果 begain··· threandA=true end··· threandA=false
3.3 sleep()方法
作用:在指定的毫秒數內讓當前正在執行的執行緒休眠(注:不會釋放鎖)
示例:
public class CreateThreandA extends Thread { private static Logger logger = LoggerFactory.getLogger(CreateThreandA.class); @Override public void run() { System.out.println("begain···"+System.currentTimeMillis()); try { Thread.sleep(2000); System.out.println("休眠中···"); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("end···"+System.currentTimeMillis()); } public static void main(String[] args) throws InterruptedException { CreateThreandA threandA = new CreateThreandA(); threandA.start(); } } //執行結果(相差2秒) begain···1541213244502 休眠中··· end···1541213246504
3.4 getId()方法
作用:獲取執行緒的唯一標識
示例:
public class CreateThreandA extends Thread { private static Logger logger = LoggerFactory.getLogger(CreateThreandA.class); @Override public void run() { } public static void main(String[] args) throws InterruptedException { CreateThreandA threandA = new CreateThreandA(); threandA.start(); System.out.println(Thread.currentThread().getName()+"--標識="+Thread.currentThread().getId()); System.out.println(threandA.getName()+"--標識="+threandA.getId()); } } //執行結果 main--標識=1 Thread-0--標識=11
3.5 interrupted()
作用:測試當前執行緒是否已經中斷(具有清除狀態的功能)
public class CreateThreandA { public static void main(String[] args) throws InterruptedException { Thread.currentThread().interrupt(); System.out.println(Thread.interrupted()); System.out.println(Thread.interrupted());//清除了true的狀態 } } //執行結果 true false
3.6 isInterrupted()
作用:測試執行緒是否已經中斷(不會清楚狀態)
public class CreateThreandA { public static void main(String[] args) throws InterruptedException { System.out.println(Thread.currentThread().isInterrupted()); Thread.currentThread().interrupt(); System.out.println(Thread.currentThread().isInterrupted()); System.out.println(Thread.currentThread().isInterrupted()); } } //執行結果 false true true
3.7 stop()
作用:暴力停止執行緒(已經廢棄,不推薦使用、所以我也不做示例了)
3.8 suspend()和resume()
作用:suspend()暫停執行緒;resume()恢復執行緒 (注:這兩種也已廢棄,不做示例演示)
3.9 yield()
作用:放棄當前CPU資源,將它讓給其他任務去佔用CPU執行時間
public class CreateThreandA extends Thread { private int count = 0; public void run(){ long time1 = System.currentTimeMillis(); for (int i=0;i<50000000;i++){ Thread.yield(); count+=i; } long time2 = System.currentTimeMillis(); System.out.println("耗時:"+(time2-time1)); } public static void main(String[] args){ CreateThreandA threandA = new CreateThreandA(); threandA.start(); } }
3.10 setPriority()
作用:設定執行緒的優先順序(注:優先順序只能是1~10、否則會報錯,執行緒的優先順序仍然無法保障執行緒的執行次序。只不過,優先順序高的執行緒獲取CPU資源的概率較大,優先順序低的並非沒機會執行。)
public class CreateThreandA extends Thread { CreateThreandA(String name){ super(name); } public void run(){ System.out.println(this.getName()); } public static void main(String[] args){ CreateThreandA threandA = new CreateThreandA("A"); CreateThreandA threandB = new CreateThreandA("B"); CreateThreandA threandC = new CreateThreandA("C"); CreateThreandA threandD = new CreateThreandA("D"); threandA.setPriority(1); threandB.setPriority(2); threandC.setPriority(3); threandD.setPriority(10); threandA.start(); threandB.start(); threandC.start(); threandD.start(); } }
3.11 wait()
作用:執行緒等待(釋放鎖)
public class CreateThreandA extends Thread { private Object lock; CreateThreandA(String name,Object lock){ super(name); this.lock=lock; } public void run(){ try { synchronized (lock){ System.out.println("上鎖"); lock.wait(); System.out.println("開鎖"); } } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args){ Object lock = new Object(); CreateThreandA threandA = new CreateThreandA("A",lock); CreateThreandA threandB = new CreateThreandA("B",lock); threandA.start(); threandB.start(); } } //執行結果 上鎖 上鎖
3.12 notify()、notifyAll()
作用:釋放鎖(notify隨機釋放一個鎖、notifyAll釋放全部鎖)
開鎖 public class CreateThreandB extends Thread { private Object lock; CreateThreandB(String name, Object lock){ super(name); this.lock=lock; } public void run(){ try { synchronized (lock){ lock.notify(); } } catch (Exception e) { e.printStackTrace(); } } } 上鎖 public class CreateThreandA extends Thread { private Object lock; CreateThreandA(String name,Object lock){ super(name); this.lock=lock; } public void run(){ try { synchronized (lock){ System.out.println("上鎖"); lock.wait(); System.out.println("開鎖"); } } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args){ Object lock = new Object(); CreateThreandA threandA = new CreateThreandA("A",lock); CreateThreandA threandB = new CreateThreandA("B",lock); CreateThreandB threand = new CreateThreandB("C",lock); threandA.start(); threandB.start(); threand.start(); } } //執行結果(印證隨機開一個鎖) 上鎖 開鎖 上鎖 notifyAll開全部鎖 修改開鎖類 lock.notifyAll(); //執行結果 上鎖 上鎖 開鎖 開鎖
3.13 join()
作用:等待執行緒物件銷燬(如果子執行緒需要較長時間執行,主執行緒往往會提前執行完畢,如果想等待子執行緒時可以採用join)
package com.chenpt.thread; import org.omg.Messaging.SYNC_WITH_TRANSPORT; /** * @Author: chen * @Description: * @Date: created in 2018/11/3 * @Modified By: */ public class CreateThreandA extends Thread { private Object lock; CreateThreandA(String name,Object lock){ super(name); this.lock=lock; } public void run(){ try { System.out.println("休眠"); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { Object lock = new Object(); CreateThreandA threandA = new CreateThreandA("A",lock); threandA.start(); threandA.join(); System.out.println("我是主執行緒,我應該等等子執行緒"); } } //執行結果 休眠 我是主執行緒,我應該等等子執行緒 (如果不加join,則主執行緒先輸出)
先總結這些基礎方法,下面注重講解進階知識