JAVA中執行緒的建立
一、執行緒(Thread)
1. 執行緒
執行緒:是指程式中的順序流
多執行緒:一個程式中的多個順序流同時執行
(1) 執行緒的狀態:
新生
就緒
執行
阻塞
終止
(2) 學習多執行緒:
1) 執行緒的建立
2) 執行緒的狀態
3) 執行緒的安全
4) 執行緒的通訊
2. 執行緒的建立
1) 繼承 Thread ,重寫 run() 方法
(1) 在 run() 方法中定義執行緒體
(2) 開啟:使用 start() 方法開啟執行緒
// 繼承 Tread
public class Thread01 extends Thread{
// 重寫 run() 方法
// 多執行緒的執行緒體
@Override
public void run() {
for(int i=1;i<=20;i++){
System.out.println(" 一邊敲程式碼 ...");
}
}
public static void main(String[] args) {
// 開啟多執行緒 建立執行緒
Thread01 th=new Thread01();
// 開啟執行緒
th.start();
//th.run(); 注意 : 這是方法的呼叫 , 不是多執行緒的開啟
for(int i=1;i<=20;i++){
System.out.println(" 一邊聊天 ...");
}
}
}
2) 實現 Runnable 介面,重寫 run() 方法(推薦使用,執行緒安全)
開啟:通過外匯返傭http://www.kaifx.cn/Tread 類中的 start() 方法開啟執行緒
優點: (1) 避免了單繼承的侷限性
(2) 實現資源的共享
public class Thread02 implements Runnable{
// 定義執行緒體的方法 , 當被呼叫的時候 , 會逐行執行裡面的程式碼
@Override
public void run() {
for(int i=1;i<=100;i++){
System.out.println(" 一邊敲程式碼 ...");
}
}
public static void main(String[] args) {
Thread02 th=new Thread02();
// 開啟執行緒 // 建立執行緒
Thread t=new Thread(th); // 因為開啟執行緒的方法在 Thread 類中 ,Thread 做為代理類出現
t.start();
for(int i=1;i<=100;i++){
System.out.println(" 一邊聊天 ...");
}
}
}
實現資源共享:
/*
* 模擬鐵路 12306
* 需求: 100 張票 ,3 個人買完
* 資源共享: 100 張票
*/
public class Thread03 implements Runnable{
// 成員 資源
int tikets=100;
@Override
public synchronized void run() {
// 迴圈買票
while(true){
if(tikets<=0){
break;
}
// 捕捉異常
//static void sleep(long millis) 在指定的毫秒數內讓當前正在執行的執行緒休眠(暫停執行),此操作受到系統計時器和排程程式精度和準確性的影響
try {
Thread.sleep(100); // 執行緒睡眠 100ms
} catch (InterruptedException e) {
e.printStackTrace();
}
//static Thread currentThread() 返回對當前正在執行的執行緒物件的引用
//String getName() 返回該執行緒的名稱
System.out.println(Thread.currentThread().getName()+" 正在購買第 "+tikets--);
}
}
public static void main(String[] args) {
Thread03 th=new Thread03 ();
// 開啟三個執行緒
Thread th1=new Thread(th," 張三 ");
Thread th2=new Thread(th," 李四 ");
Thread th3=new Thread(th," 王五 ");
th1.start();
th2.start();
th3.start();
}
}
3) 實現 Callable 介面,重寫 call() 方法,方法中定義執行緒體(瞭解)
優點:可以丟擲異常,可以有返回值
// 導包
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
// 實現 Callable 介面 <> 可以新增泛型,引用型別的資料
public class Race05 implements Callable<Integer>{
// 儲存贏的人的名字
String winner=null;
// 重寫 call() 方法,方法中定義執行緒體
@Override
public Integer call() throws Exception {
// 開始遊戲 , 迴圈停止遊戲結束
for(int i=1;i<=100;i++){
if(" 兔子 ".equals(Thread.currentThread().getName()) && i%10==0){
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" 正在跑第 "+i+" 步 ");
// 呼叫有 Boolean 型別返回值的結束方法
boolean flag=over(i);
// 判斷返回值是 true ,或為 false
if(flag){
return i;
}
}
return -1;
}
/**
* @param steps 當前執行緒的步數
* 返回值 : 如果有人贏了返回 true, 否則返回 false
*/
public boolean over(int steps){
if(winner!=null){
return true;
}else{
if(steps==100){
winner=Thread.currentThread().getName();
return true;
}
return false;
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
Race05 race=new Race05();
//1. 建立執行服務
ExecutorService server=Executors.newFixedThreadPool(2);
//2. 提交執行
Future result1=server.submit(race);
Future result2=server.submit(race);
//3. 獲取結果
Integer i1=(Integer) result1.get();
Integer i2=(Integer) result2.get();
System.out.println(i1+"---->"+i2);
//4. 關閉服務
server.shutdown();
}
}
2. 執行緒狀態問題
1) 狀態:
新生狀態: new
就緒狀態: start() 執行緒就會進入到就緒狀態 , 執行緒會進入到就緒佇列 , 等待 CPU 的排程
執行狀態:
阻塞狀態: 非常執行完畢 , 通過程式進行控制
終止狀態:
注意: 一個執行緒一旦進入到終止狀態 , 沒有辦法恢復了 , 就算是重寫 new 一個執行緒 , 也不剛那個執行緒了,一個執行緒一旦進入到阻塞狀態 , 無法直接恢復到執行 , 等待阻塞接觸之後恢復到就緒狀態
2) 如何進入到就緒狀態
1 ) start()
2 )阻塞解除
3 )執行緒切換,被切換的執行緒進入到就緒狀態
4 ) yield() 禮讓執行緒
3) 如何進入到阻塞狀態
1 ) sleep() 方法
2 ) join()
3 ) wait()
4) 如何讓一個執行緒進入到終止狀態
1 )正常執行完畢
2 ) destroy() |stop() 已過時
3 )通過標識手動判斷
3.Thread 類的方法學習
1 ) sleep() 執行緒休眠
1. 模擬網路延遲
2. 放大問題的可能性
注意:sleep() 執行緒的休眠是抱著資源不放進行休眠,同步的是物件資源,讓出的是 CPU 的資源
// 實現 Runnable 介面
public class State01 implements Runnable{
public static void main(String[] args) {
new Thread(new State01()).start();
}
/*
* 倒數計時 10 9 8 7 6 5 4 3 2 1
* 重寫 run() 方法
*/
@Override
public void run() {
for(int i=10;i>=0;i--){
// 模擬網路延遲
try {
Thread.sleep(1000); //sleep() 執行緒的休眠 1000ms=1s
} catch (InterruptedException e) {
e.printStackTrace();
}
if(i==0){
System.out.println(" 過年好 ...");
break;
}
System.out.println(i);
}
}
}
2 ) yield() 禮讓執行緒
static Thread currentThread()
返回對當前正在執行的執行緒物件的引用
String getName()
返回該執行緒的名稱
//static void yield() 暫停當前正在執行的執行緒物件,並執行其他執行緒
public class Yield03 implements Runnable{
public static void main(String[] args) {
new Thread(new Yield03(),"A").start();
new Thread(new Yield03(),"B").start();
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"start...");
//yield() 禮讓執行緒,等待 CPU 的再度呼叫,但是是隨機分配
Thread.yield(); // 靜態方法
System.out.println(Thread.currentThread().getName()+"end...");
}
}
3 ) getState() 方法
Thread.State getState()
返回該執行緒的狀態
void setPriority(int newPriority)
更改執行緒的優先順序
/*
* getState() 方法
* 執行緒的優先順序: 提高優先執行的可能性 , 但是不一定就會先執行
* void setPriority(int newPriority) 更改執行緒的優先順序。
* 優先順序分為1~10 1 最小 10 最大
* Thread.NORM_PRIORITY 5 ( 預設為 5)
* Thread.MAX_PRIORITY 10
* Thread.MIN_PRIORITY 1
*/
public class GetState04 {
public static void main(String[] args) {
Thread th=new Thread(()->{
for(int i=1;i<=10;i++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(" 一邊學習 ...");
}
});
th.setPriority(Thread.NORM_PRIORITY);
System.out.println(th.getPriority());
System.out.println(th.getState());//NEW
th.start();
System.out.println(th.getState());//RUNNABLE
for(int i=1;i<=10;i++){
if(i==5){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(th.getState());
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(th.getState());
if(th.getState()== Thread.State.TERMINATED){
System.out.println(" 終止 ");
}
}
}
4 ) join() 合併執行緒,插隊執行緒
void join()
等待該執行緒終止。
void join(long millis)
等待該執行緒終止的時間最長為 millis 毫秒。
void join(long millis, int nanos)
等待該執行緒終止的時間最長為 millis 毫秒 + nanos 納秒
/*
* join() 合併執行緒 , 插隊執行緒
模擬:父親讓兒子去買菸的過程
*/
public class JoinDemo05 {
public static void main(String[] args) {
new Thread(new Father()).start();
}
}
class Father implements Runnable{
@Override
public void run() {
System.out.println(" 想抽菸 ...");
System.out.println(" 給兒子錢,讓兒子去買菸 ..");
Thread th=new Thread(new Son());
th.start();
try {
th.join();// 合併執行緒
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(" 兒子丟了 , 趕緊去找兒子 ..");
}
System.out.println(" 接過煙 , 吸一口 , 啊 ~");
}
}
class Son implements Runnable{
@Override
public void run() {
System.out.println(" 接過前 , 給老爸去買菸 ...");
System.out.println(" 路邊有個電玩城 , 進去玩 10s...");
for(int i=1;i<=10;i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i+"s...");
}
System.out.println(" 趕緊去買菸 ...");
System.out.println(" 把煙給老爸 , 前揣兜裡 ...");
}
}
4. 執行緒安全
多個執行緒同時操作同一個資源的時候, 才可能會出現執行緒安全問題
1 ) synchronized 關鍵字
通過同步synchronized 關鍵字控制執行緒安全 :
同步方法 :
靜態方法
成員方法
同步塊 synchronized ( 類 |this| 資源 ){ 程式碼 }
類: 類名 .class 一個類的 Class 物件 一個類只有一個 Class 物件
// 通過同步 synchronized 關鍵字控制執行緒安全
public class Single01 {
public void main(String[] args) {
new Thread(()->{System.out.println(Single.newInstance());}).start();;
new Thread(()->{System.out.println(Single.newInstance());}).start();;
}
}
class Single{
//2. 私有的靜態的該類的引用
private static Single single=null;
//1. 構造器私有話
private Single(){}
//3. 公共的靜態的方法
// 在方法上新增鎖 , 鎖方法
/*public static synchronized Single newInstance(){
if(single==null){
single=new Single();
}
return single;
}*/
// 同步塊
/*public static Single newInstance(){
synchronized (Single.class) { // 控制多執行緒排隊執行
if(single==null){
single=new Single();
}
} //{} 中的程式碼就是排隊執行的程式碼
return single;
}*/
public static Single newInstance(){
if(single==null){
//A B C
synchronized (Single.class) { // 控制多執行緒排隊執行
// 雙重檢查 double check
if(single==null){
single=new Single();
}
} //{} 中的程式碼就是排隊執行的程式碼
}
return single;
}
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946279/viewspace-2662888/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【Java】執行緒的建立方式Java執行緒
- Java 中執行緒池的7種建立方式!Java執行緒
- 【java】【多執行緒】建立執行緒的兩種常用方式(2)Java執行緒
- Java多執行緒學習(1)建立執行緒與執行緒的生命週期Java執行緒
- Java中的執行緒Java執行緒
- Java 執行緒建立與常用方法Java執行緒
- Java 中的執行緒 threadJava執行緒thread
- JAVA中的執行緒世界Java執行緒
- Java執行緒的中斷Java執行緒
- Java中的多執行緒Java執行緒
- Java中的執行緒同步Java執行緒
- Java中的執行緒-1Java執行緒
- java建立執行緒池的幾中方式Java執行緒
- Java建立多執行緒的四種方式Java執行緒
- Java建立多執行緒的一種方法Java執行緒
- 執行緒池建立執行緒的過程執行緒
- java--執行緒池--建立執行緒池的幾種方式與執行緒池操作詳解Java執行緒
- 【JAVA併發第二篇】Java執行緒的建立與執行,執行緒狀態與常用方法Java執行緒
- java中執行緒池的生命週期與執行緒中斷Java執行緒
- java的執行緒、建立執行緒的 3 種方式、靜態代理模式、Lambda表示式簡化執行緒Java執行緒模式
- 多執行緒------執行緒與程式/執行緒排程/建立執行緒執行緒
- Java中多執行緒的案例Java執行緒
- Java併發(三)----建立執行緒的三種方式及檢視程式執行緒Java執行緒
- Java中命名執行器服務執行緒和執行緒池Java執行緒
- Java併發基礎01:揭祕傳統執行緒技術中建立執行緒的兩種方式Java執行緒
- 認識執行緒、建立執行緒寫法執行緒
- 【Java多執行緒】執行緒安全的集合Java執行緒
- Java多執行緒-執行緒池的使用Java執行緒
- Java執行緒篇——執行緒的開啟Java執行緒
- Java基礎:執行緒的三種建立方式Java執行緒
- Java建立多執行緒的幾種方式實現Java執行緒
- jdk建立執行緒的方式JDK執行緒
- Java中的多執行緒詳解Java執行緒
- Java中的執行緒同步詳解Java執行緒
- 淺析Java中的執行緒池Java執行緒
- Java中實現執行緒的方式Java執行緒
- Java的Interrupt與執行緒中斷Java執行緒
- Java多執行緒中執行緒安全與鎖問題Java執行緒