日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java核心类库篇7——多线程

發布時間:2025/3/12 java 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java核心类库篇7——多线程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java核心類庫篇7——多線程

1、程序、進程和線程

  • 程序 - 數據結構 + 算法,主要指存放在硬盤上的可執行文件
  • 進程 - 主要指運行在內存中的可執行文件
  • 線程就是進程內部的程序流

操作系統內部支持多 進程的,而每個進程的內部又是支持多線程的

2、線程的創建

方法聲明功能介紹
public Thread()使用無參的方式構造對象
public Thread(String name)根據參數指定的名稱來構造對象
public Thread(Runnable target)根據參數指定的引用來構造對象,其中Runnable是個接口類型
public Thread(Runnable target, String name)根據參數指定引用和名稱來構造對象
public void run()若使用Runnable引用構造了線程對象,調用該方法時最終調 用接口中的版本 若沒有使用Runnable引用構造線程對象,調用該方法時則啥也不做
public void start()用于啟動線程,Java虛擬機會自動調用該線程的run方法
public long getId()獲取調用對象所表示線程的編號
public String getName()獲取調用對象所表示線程的名稱
public void setName(String name)設置/修改線程的名稱為參數指定的數值
public static Thread currentThread()獲取當前正在執行線程的引用

2.1、繼承Thread類

  • 優點:實現起來簡單,而且要獲取當前線程,無需調用Thread.currentThread()方法,直接使用this即可獲取當前線程
  • 缺點:線程類已經繼承Thread類了,就不能再繼承其他類,多個線程不能共享同一份資源
public class MyThread extends Thread {@Overridepublic void run() {for (int i = 0; i < 50; i++) {System.out.println(this.getName()+"----------------"+i);}} } public class Test {public static void main(String[] args) {new MyThread().start();for (int i = 0; i < 50; i++) {System.out.println(Thread.currentThread().getName()+"----------------"+i);}} }

注:直接調用run方法如同調用類成員方法一樣

2.2、實現Runnable接口

  • 優點:線程類只是實現了接口,還可以繼承其他類,多個線程可以使用同一個target對象,適合多個線程處理同一份資源的情況
  • 缺點:通過這種方式實現多線程,相較于第一類方式,編程較復雜,要訪問當前線程,必須調用Thread.currentThread()方法
public class MyRunable implements Runnable {@Overridepublic void run() {for (int i = 0; i < 50; i++) {System.out.println(Thread.currentThread().getName()+"----------------"+i);}} } public class Test {public static void main(String[] args) {new Thread(new MyRunable()).start();for (int i = 0; i < 50; i++) {System.out.println(Thread.currentThread().getName()+"----------------"+i);}} }

2.3、Callable和FutureTask

  • 優點:線程類只是實現了接口,還可以繼承其他類,多個線程可以使用同一個target對象,適合多個線程處理同一份資源的情況
  • 缺點:通過這種方式實現多線程,相較于第一類方式,編程較復雜,要訪問當前線程,必須調用Thread.currentThread()方法
public class Test {public static void main(String[] args) throws ExecutionException, InterruptedException {FutureTask<Integer> futureTask=new FutureTask<Integer>(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {for (int i = 0; i < 50; i++) {System.out.println(Thread.currentThread().getName()+"----------------"+i);}return 100;}});new Thread(futureTask, "ruoye").start();for (int i = 0; i < 50; i++) {System.out.println(Thread.currentThread().getName()+"----------------"+i);}System.out.println(futureTask.get());} }

lambda表達式

public class Test {public static void main(String[] args) throws ExecutionException, InterruptedException {FutureTask<Integer> futureTask = new FutureTask<>((Callable<Integer>) () -> {System.out.println("hello world!");return 100;});new Thread(futureTask, "ruoye").start();for (int i = 0; i < 50; i++) {System.out.println(Thread.currentThread().getName()+"----------------"+i);}System.out.println(futureTask.get());} }

3、線程優先級及線程讓步

方法聲明功能介紹
public static void yield()當前線程讓出處理器(離開Running狀態),使當前線程進入Runnable 狀態等待
public static void sleep(times)使當前線程從 Running 放棄處理器進入Block狀態, 休眠times毫秒
public int getPriority()獲取線程的優先級
public void setPriority(int newPriority)修改線程的優先級,優先級越高的線程不一定先執行,但該線程獲取到時間片的機會會更多 一些
public void join()等待該線程終止
public void join(long millis)等待參數指定的毫秒數
public boolean isDaemon()用于判斷是否為守護線程
public void setDaemon(boolean on)用于設置線程為守護線程

sleep

public class Test {public static void main(String[] args) {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");while (true){System.out.println(simpleDateFormat.format(new Date()));try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}} }

setPriority線程優先級

public class Test {public static void main(String[] args) {Thread thread = new Thread(() -> {System.out.println(Thread.currentThread().getName()+"優先級-----"+Thread.currentThread().getPriority());for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName()+"-----"+i);}});thread.setName("ruoye");thread.setPriority(Thread.MAX_PRIORITY);thread.start();for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName()+"-----"+i);}} }

線程等待

public class Test {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {for (int i = 0; i < 10; i++) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"-----"+i);}});thread.setName("ruoye");thread.start(); // thread.join(); // System.out.println("終于等到你");thread.join(5000);System.out.println("沒有等到你");} }

守護線程

public class Test {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {for (int i = 0; i < 10; i++) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"-----"+i);}});thread.setName("ruoye");thread.setDaemon(true);thread.start();Thread.sleep(5000);System.out.println("沒有等到你");} }

4、線程同步

4.1、多線程出現的問題

public class Account implements Runnable {private int money;public Account(int money) {this.money = money;}public int getMoney() {return money;}public void setMoney(int money) {this.money = money;}@Overridepublic void run() {System.out.println("進到門口");System.out.println("開始取鈔");if (this.money>200){try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}this.money-=200;System.out.println("取款成功");}}@Overridepublic String toString() {return "Account{" +"money=" + money +'}';} } public class Test {public static void main(String[] args) throws InterruptedException {Account account = new Account(1000);Thread thread = new Thread(account);Thread thread1 = new Thread(account);thread.start();thread1.start();thread.join();thread1.join();System.out.println(account.getMoney());} }

4.2、synchronized同步鎖

4.2.1、synchronized代碼塊

下面所示為鎖class,鎖Account對象里的成員變量(對象)也可,但請時刻記住,多個Account為對象里的成員變量(對象)多個對象,那么就擁有了多把鎖,此時應當用static修飾

休眠在同步代碼塊內不會讓出cpu

public class Account implements Runnable {private int money;public Account(int money) {this.money = money;}public int getMoney() {return money;}public void setMoney(int money) {this.money = money;}@Overridepublic void run() {System.out.println("進到門口");synchronized (Account.class){System.out.println("開始取鈔");if (this.money>200){try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}this.money-=200;System.out.println("取款成功");}}}@Overridepublic String toString() {return "Account{" +"money=" + money +'}';} } public class Test {public static void main(String[] args) throws InterruptedException {Account account = new Account(1000);Thread thread = new Thread(account);Thread thread1 = new Thread(account);thread.start();thread1.start();thread.join();thread1.join();System.out.println(account.getMoney());} }

4.2.2、synchronized方法

當synchronized位于成員方法上等價于synchronized (this)

當當synchronized位于成員方法上等價于synchronized (類對象)

public class Account implements Runnable {private int money;public Account(int money) {this.money = money;}public int getMoney() {return money;}public void setMoney(int money) {this.money = money;}@Overridepublic synchronized void run() {System.out.println("進到門口");System.out.println("開始取鈔");if (this.money>200){try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}this.money-=200;System.out.println("取款成功");}}@Overridepublic String toString() {return "Account{" +"money=" + money +'}';} } public class Test {public static void main(String[] args) throws InterruptedException {Account account = new Account(1000);Thread thread = new Thread(account);Thread thread1 = new Thread(account);thread.start();thread1.start();thread.join();thread1.join();System.out.println(account.getMoney());} }

4.3、死鎖問題

盡量減少同步的資源,減少同步代碼塊的嵌套結構的使用

線程一執行的代碼

public void run(){synchronized(a){ //持有對象鎖a,等待對象鎖b synchronized(b){ //編寫鎖定的代碼; }} }

線程二執行的代碼

public void run(){synchronized(b){ //持有對象鎖a,等待對象鎖b synchronized(a){ //編寫鎖定的代碼; }} }

4.4、Lock鎖

  • Lock是顯式鎖,需要手動實現開啟和關閉操作,而synchronized是隱式鎖,執行鎖定代碼后自動釋放
  • Lock只有同步代碼塊方式的鎖,而synchronized有同步代碼塊方式和同步方法兩種鎖
  • 使用Lock鎖方式時,Java虛擬機將花費較少的時間來調度線程,因此性能更好
public class Account implements Runnable {private int money;private static Lock lock=new ReentrantLock();public Account(int money) {this.money = money;}public int getMoney() {return money;}public void setMoney(int money) {this.money = money;}@Overridepublic void run() {lock.lock();System.out.println("進到門口");System.out.println("開始取鈔");if (this.money>200){try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}this.money-=200;System.out.println("取款成功");}lock.unlock();}@Overridepublic String toString() {return "Account{" +"money=" + money +'}';} } public class Test {public static void main(String[] args) throws InterruptedException {Account account = new Account(1000);Thread thread = new Thread(account);Thread thread1 = new Thread(account);thread.start();thread1.start();thread.join();thread1.join();System.out.println(account.getMoney());} }

5、線程通信

5.1、線程通信

不能鎖class

public class Account implements Runnable {private int a;public Account(int a) {this.a = a;}@Overridepublic void run() {while (true){synchronized (this) {if (a<100){System.out.println(Thread.currentThread().getName()+"========"+a);a++;notify();try {wait();} catch (InterruptedException e) {e.printStackTrace();}}else{break;}}}} } public class Test {public static void main(String[] args) throws InterruptedException {Account account = new Account(1);Thread ruoye = new Thread(account, "ruoye");Thread yoya = new Thread(account, "yoya");ruoye.start();yoya.start();} }

5.2、生產者消費者問題

  • 線程間的通信共享數據一定要有同步代碼塊synchronized
  • 一定要有wait和notify,而且二者一定是成對出現
  • 生產者和消費者的線程實現一定是在while(true)里面
public class Mother implements Runnable {private Account account;public Mother(Account account) {this.account = account;}@Overridepublic void run() {while (true){try {account.produce();Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}} } public class Ming implements Runnable {private Account account;public Ming(Account account) {this.account = account;}@Overridepublic void run() {while (true){try {account.consumer();Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}} } public class Account {private int a;public Account(int a) {this.a = a;}public int getA() {return a;}public void setA(int a) {this.a = a;}public synchronized void produce() throws InterruptedException {notify();if (a<2000){a+=100;System.out.println("媽媽給小明存了100元");}else{wait();}}public synchronized void consumer() throws InterruptedException {notify();if (a>75){a-=75;System.out.println("小明花了75元");}else{wait();}} } public class Test {public static void main(String[] args) throws InterruptedException {Account account = new Account(0);new Thread(new Mother(account)).start();new Thread(new Ming(account)).start();} }

總結

以上是生活随笔為你收集整理的Java核心类库篇7——多线程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。