JAVA多執行緒
執行緒創建
1.Thread類
-
自定義執行緒類繼承Thread類
-
重寫run()方法,撰寫執行緒執行體
-
創建執行緒物件,呼叫start()方法啟動執行緒
//創建執行緒方式一:繼承Thread類 重寫run()方法,呼叫start開啟執行緒
public class TestThread1 extends Thread{
@Override
public void run() {
//run方法執行緒體
for (int i = 0; i < 20; i++) {
System.out.println("我在看代碼"+i);
}
}
//main執行緒,主執行緒
public static void main(String[] args) {
//創建一個執行緒物件
TestThread1 testThread1 = new TestThread1();
//呼叫start()方法開啟執行緒(交替執行)
testThread1.start();
//呼叫run()方法先執行run()再執行主方法
//testThread1.run();
for (int i = 0; i < 20; i++) {
System.out.println("我在執行多執行緒"+i);
}
?
}
}
?
/*注意!執行緒開啟不一定立即執行,由CPU調度執行*/
2.Runnable介面(實作Runnable介面)推薦
-
定義MyRunnable類實作Runnable介面
-
實作run()方法,撰寫執行緒執行體
-
創建執行緒物件,呼叫start()方法啟動執行緒
//創建執行緒方式2:實作runnable介面,重寫run方法,執行執行緒需要丟入runnable類介面實作類,呼叫start方法
public class TestThread3 implements Runnable{
@Override
public void run() {
//run方法執行緒體
for (int i = 0; i < 20; i++) {
System.out.println("我在看代碼"+i);
}
}
?
public static void main(String[] args) {
//創建runnable介面的實作類物件
TestThread3 testThread3 = new TestThread3();
//創建執行緒物件,通過執行緒物件來開啟我們的執行緒
Thread thread = new Thread(testThread3);
?
thread.start();
?
//簡寫 newThread(testThread3).start();
?
for (int i = 0; i < 20; i++) {
System.out.println("我在執行多執行緒"+i);
}
?
}
}
3.Callable介面(實作Callable介面)
-
實作Callable介面,需要回傳值型別
-
重寫call方法,需要拋出例外
-
創建目標物件
-
創建執行服務
ExecutorService ser = Executors.newFixedThreadPool(1);
-
提交執行
Future<Boolean>result1 = ser.submit(t1);
-
獲取結果
boolean r1 = result.get()
-
關閉服務
ser.shutdownNow();
/*圖片下載案例 callable方法實作*/ ?
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;
?
/**
* TODO
*
* @author wlj
* @version 1.0
* @Description
* @date 2022/1/15 16:39
*/
?
/*
callable的好處
可以拋出例外
具有回傳值
*/
?
//執行緒創建方式三:實作callable介面
public class TestCallable implements Callable<Boolean> {
private String url;//網路圖片地址
private String name;//保存的檔案名
?
public TestCallable(String url, String name) {
this.url = url;
this.name = name;
}
?
?
@Override
public Boolean call() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url, name);
System.out.println("下載了檔案名為:" + name);
return true;
}
?
public static void main(String[] args) throws ExecutionException, InterruptedException {
?
?
TestCallable testThread1 = new TestCallable("https://webstatic.mihoyo.com/upload/puzzle/2021/12/22/1a4f9ac397162af7b11616ea7acb5115_4472408160447119381.png", "1.jpg");
TestCallable testThread2 = new TestCallable("https://webstatic.mihoyo.com/upload/puzzle/2021/12/22/1a4f9ac397162af7b11616ea7acb5115_4472408160447119381.png", "2.jpg");
TestCallable testThread3 = new TestCallable("https://webstatic.mihoyo.com/upload/puzzle/2021/12/22/1a4f9ac397162af7b11616ea7acb5115_4472408160447119381.png", "3.jpg");
?
/*======================================================================*/
//創建執行服務 執行緒池
ExecutorService ser = Executors.newFixedThreadPool(3);
?
//提交執行
Future<Boolean> r1 = ser.submit(testThread1);
Future<Boolean> r2 = ser.submit(testThread2);
Future<Boolean> r3 = ser.submit(testThread3);
?
//獲取結果
boolean rs1 = r1.get();
boolean rs2 = r2.get();
boolean rs3 = r3.get();
?
//列印回傳結果
System.out.println(rs1);
System.out.println(rs2);
System.out.println(rs3);
?
//關閉服務
ser.shutdownNow();
/*====================================================================*/
}
}
?
?
//下載器
class WebDownloader {
//下載方法
public void downloader(String url, String name) {
try {
FileUtils.copyURLToFile(new URL(url), new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO例外,downloader方法出現問題");
}
}
}
執行緒休眠
-
sleep(時間)指定當前執行緒阻塞的毫秒數
-
sleep存在例外InterruptedException
-
sleep時間達到后執行緒進入就緒狀態
-
sleep可以模擬網路延時,倒計時
-
每一個物件都有一個鎖,sleep不會釋放鎖
//模擬倒計時
public class TestSleep2 {
public static void main(String[] args) {
// try {
// tenDown();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
?
//列印當前時間
Date startTime = new Date(System.currentTimeMillis());//獲取當前系統時間
while(true){
try {
Thread.sleep(1000);
System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));
startTime = new Date(System.currentTimeMillis());//更新當前時間
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
?
public static void tenDown() throws InterruptedException{
int num = 10;
while (true) {
Thread.sleep(1000);
System.out.println(num--);
if(num<=0){
break;
}
}
}
}
執行緒關閉
-
不推薦使用JDK提供的stop(),destory()方法【已廢棄】
-
推薦執行緒自己停止下來
-
建議使用一個標志位進行終止變數,當flag = false,則終止執行緒運行
//測驗stop
//1.建議執行緒正常停止--->利用次數,不建議死回圈
//2.建議使用標志位--->攝制一個標志位
//3.不要使用stop或者destroy等過時或者JDK不建議使用的方法
public class TestStop implements Runnable{
//1.設定一個標識位
private boolean flag = true;
@Override
public void run() {
int i = 0;
while(flag){
System.out.println("run...Thread"+i++);
}
}
//2.設定一個公開的方法停止執行緒,轉換標志位
public void stop(){
this.flag = false;
}
public static void main(String[] args) {
TestStop testStop = new TestStop();
new Thread(testStop).start();
for (int i = 0; i < 1000; i++) {
System.out.println("main"+i);
if(i == 900){
//呼叫自己寫的stop方法切換標志位,讓執行緒停止
testStop.stop();
}
}
}
}
執行緒禮讓
-
禮讓執行緒,讓當前正在執行的執行緒暫停,但不阻塞
-
將執行緒從運行狀態轉為就緒狀態
-
讓CPU重新調度,禮讓不一定成功
//測驗禮讓執行緒
//禮讓不一定成功,看CPU心情
public class TestYield {
public static void main(String[] args) {
MyYield myYield = new MyYield();
new Thread(myYield,"a").start();
new Thread(myYield,"b").start();
}
}
class MyYield implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"執行緒開始執行");
Thread.yield();//禮讓
System.out.println(Thread.currentThread().getName()+"執行緒停止執行");
}
}
執行緒強制執行
//測驗Join方法, 想象為插隊
public class TestJoin implements Runnable{
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("vip執行緒來了"+i);
}
}
public static void main(String[] args) throws InterruptedException{
//啟動我們的執行緒
TestJoin testJoin = new TestJoin();
Thread thread = new Thread(testJoin);
thread.start();
//主執行緒
for (int i = 0; i < 500; i++) {
if(i == 200){
thread.join();//插隊
}
System.out.println("main"+i);
}
}
}
執行緒狀態觀察
public class TestState {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("///");
});
//觀察狀態
Thread.State state = thread.getState();
System.out.println(state); //NEW
//觀察啟動后
thread.start();//啟動執行緒
state = thread.getState();
System.out.println(state);//Run
while(state != Thread.State.TERMINATED){//只要執行緒不終止 就一直輸出狀態
Thread.sleep(100);
state = thread.getState();//更新執行緒狀態
System.out.println(state);//列印執行緒狀態
}
}
}
執行緒優先級
執行緒的優先級用數字表示,范圍從1~10
-
Thread.MIN_PRIORITY = 1;
-
Thread.MAX_PRIORITY = 10;
-
Thread.NORM_PRIORITY = 5;
使用以下方式改變或獲取優先級
-
getPriority()
-
setPriority(int xxx)
public class TestPriority {
?
public static void main(String[] args) {
//主執行緒默認優先級
System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
?
MyPriority myPriority = new MyPriority();
Thread t1 = new Thread(myPriority);
Thread t2 = new Thread(myPriority);
Thread t3 = new Thread(myPriority);
Thread t4 = new Thread(myPriority);
Thread t5 = new Thread(myPriority);
Thread t6 = new Thread(myPriority);
?
//先設定優先級,在啟動
t1.start();
t2.setPriority(1);
t2.start();
t3.setPriority(4);
t3.start();
t4.setPriority(Thread.MAX_PRIORITY);
t4.start();
?
}
}
?
class MyPriority implements Runnable{
?
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
}
}
守護執行緒
-
執行緒分為用戶執行緒和守護執行緒
-
虛擬機必須確保用戶執行緒執行完畢
-
虛擬機不用等待守護執行緒執行完畢
-
如:后臺記錄操作日志,監控記憶體,垃圾回收等待
//測驗守護執行緒
public class TestDaemon {
public static void main(String[] args) {
God god = new God();
You you = new You();
?
Thread thread = new Thread(god);
thread.setDaemon(true);//默認是false表示是用戶執行緒,正常的執行緒都是用戶執行緒
thread.start();//上帝守護執行緒啟動
?
new Thread(you).start();//你 用戶執行緒啟動
?
}
}
?
//上帝
?
class God implements Runnable{
@Override
public void run() {
while(true){
System.out.println("上帝保佑你");
}
}
}
?
//你
class You implements Runnable{
@Override
public void run() {
for (int i = 0; i < 36500; i++) {
System.out.println("你一生都開心地活著");
}
System.out.println("-====goodbye! world!====-");
}
}
?
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/413934.html
標籤:其他
