android基礎學習-java篇day9-step3-第五節:java執行緒
目錄
- -執行緒的概念
- -建立執行緒的兩種方式
- -執行緒的狀態和生命週期
- -sleep()和join方法
- -執行緒的優先順序
- -同步
- -執行緒間通訊
什麼是程式?
程式是一個執行的程式;
是指可執行程式並存放在計算機儲存器的一個指令序列,它是一個動態執行的過程。
什麼是執行緒?
執行緒是比程式還要小的執行單位,一個程式包含多個執行緒;
執行緒可以看做是一個子程式。
執行緒的建立
- 建立一個Thread類,或者一個Thread子類的物件
- 子類繼承Thread類
- 在子類中重寫run()方法
- 主方法main中呼叫start()方法啟動執行緒
- 建立一個實現Runnable介面的類的物件
通過執行緒實現類建立物件
將實現類的物件建立Thread的物件2
將實現類的物件建立Thread的物件2
Thread類
Thread是一個執行緒類,位於java.lang包下
構造方法 | 說明 |
Thread() | 建立一個執行緒物件 |
Tread(String name) | 建立一個具有指定名稱的執行緒物件 |
Thread(Runnable target) | 建立一個基於Runnable介面實現類的執行緒物件 |
Tread(Runnable target,String name) | 建立一個基於Runnable介面實現,並且指定名稱的執行緒物件 |
Thread類的常用方法
方法 | 說明 |
public void run() | 執行緒相關的程式碼寫在該方法中,一般需要重寫 |
public void start() | 啟動執行緒的方法 |
public static void sleep(long m) | 執行緒休眠m毫秒的方法 |
public void join() | 優先執行呼叫join()方法的執行緒 |
Runnable介面
- 只有一個run();方法
- Runnable是java中實現執行緒的介面
- 實現執行緒功能的類都必須實現該介面
1、執行緒的簡單建立-繼承Thread:
package com.demo.day9.thread;
/*
* 通過基礎Thread類的方式建立執行緒類,重寫run()方法
*/
class MyThread extends Thread{
public void run() {
System.out.println(getName()+"該執行緒正在執行!");
}
}
public class ThreadTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("主執行緒1");
MyThread mt=new MyThread();//建立物件
mt.start();//呼叫start()方法啟動執行緒,執行run方法
//start();只能執行一次
System.out.println("主執行緒2");
}
}
執行緒使用CPU的使用權是隨機的:
package com.demo.day9.thread;
class MyThreadOne extends Thread {
//構造方法,給執行緒取個名字
public MyThreadOne(String name) {
super(name);
}
public void run() {
for(int i=1;i<10;i++) {
System.out.println(getName()+"正在執行"+i+"次");
}
}
}
public class TreadOne {
public static void main(String[] args) {
//建立執行緒物件
MyThreadOne mt1=new MyThreadOne("執行緒1");
MyThreadOne mt2=new MyThreadOne("執行緒2");
mt1.start();
mt2.start();
//執行緒獲取CPU的使用權是隨機的、執行結果隨機
}
}
輸出結果隨機。。
2、執行緒建立-實現Runnale介面建立執行緒
為什麼要實現Runnable介面?
- java不支援多繼承
- 不打算重寫Thread類的其他方法
- java支援實現多介面
簡單案例:
package com.demo.day9.thread;
/*
* 通過實現Runnable介面建立執行緒
*/
//建立執行緒實現類 PrintRunnale
class PrintRunnable implements Runnable{
@Override
public void run() {
//輸出正在進行的執行緒
int i=1;
while(i<10)
System.out.println(Thread.currentThread().getName()+"正在進行"+(i++)+"次");
//Thread.currentThread().getName() 獲取當前正在進行執行緒的名字
}
}
public class MyRunnable {
public static void main(String[] args) {
//通過執行緒實現類建立物件
PrintRunnable pt =new PrintRunnable();
//將實現類的物件建立Thread的物件2
Thread th=new Thread(pt);
th.start();
//將實現類的物件建立Thread的物件2
//兩個物件共用一個實現類物件
Thread th2=new Thread(pt);
th2.start();
}
}
執行緒的狀態和生命週期
執行緒的五個狀態
- 新建(New)
- 可執行(Runnable)(又叫就緒)
- 正在執行狀態(Running)
- 阻塞(Blocked)
- 終止(Dead)
執行緒的生命週期
sleep方法的應用
- Thread類的方法
public static void sleep(long millis)
- 作用:在指定的毫秒數內讓正在執行的執行緒休眠,暫停執行
- 引數為休眠的時間,單位是毫秒
package com.demo.day9.thread;
//通過實現Runnable介面建立執行緒
class MyThreadTwo implements Runnable{
@Override
public void run() {
for(int i=1;i<15;i++) {
System.out.println(Thread.currentThread().getName()+"正在進行"+i+"次");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//讓執行緒休眠1秒
}
}
}
public class ThreadTwo {
public static void main(String[] args) {
// 建立執行緒類物件
MyThreadTwo mt=new MyThreadTwo();
//通過執行緒類物件建立Thread類物件呼叫start方法
Thread th=new Thread(mt);
th.start();
}
}
join方法的使用(強制CPU控制權)
- Thread類的方法
public final void join()
- 作用:等待呼叫該方法的執行緒結束後,之後的執行緒才能執行
public final void join(long millis)
作用:等待該執行緒終止的最長時間為millis毫秒,無論該執行緒是否執行完,要釋放CPU控制權
執行緒的優先順序
- java為執行緒類提供了10個優先順序
- 優先順序可以用整數1-10表示,超過範圍會丟擲異常
- 主執行緒預設優先順序為5
- 優先順序常量
- -MAX_PRIORITY:執行緒的最高優先順序10
- -MIN_PROIRITY:執行緒的最低優先順序1
- -NORM_PROIRITY:執行緒的預設優先順序
- 優先順序相關的方法
方法 | 說明 |
public int getPriority() | 獲取執行緒的優先順序的方法 |
public void setPriority() | 設定執行緒的優先順序的方法 |
執行緒同步synchronized
多執行緒執行存在的問題
各個執行緒是通過競爭CPU時間而獲得執行機會的
- 各執行緒什麼時候得到CPU時間,佔用多久,是不可預測的
- 一個正在執行著的執行緒在什麼地方被暫停是不確定的
銀行存取款案例:
Bank.java
package com.demo.day9.thread;
public class Bank {
private int balance;//賬戶餘額
private String account;//賬戶
//帶參構造,為變數賦值
public Bank(String account,int balance) {
this.setAccount(account);
this.setBalance(balance);
}
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
//重寫toString
public String toString() {
return "賬戶為:"+this.getAccount()+" "+"餘額為:"+this.getBalance();
}
//存錢的方法
public void savaAccount(){
synchronized (this){//同步,執行這個執行緒,不允許其他執行緒搶佔CPU
int balance=getBalance();//獲取當前賬戶餘額
try {
Thread.sleep(1000);//讓執行緒休眠1秒
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
balance+=100;//存入100元
setBalance(balance);//
System.out.println("存款後賬戶餘額:"+balance);
}
}
public void drawAccouct() {
int balance=getBalance();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
balance-=200;//取款200
setBalance(balance);
System.out.println("取款後賬戶餘額:"+balance);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
SaveAccount.java
package com.demo.day9.thread;
/*
* 存款
*/
//通過實現Runnable介面來建立執行緒
public class SaveAccount implements Runnable{
Bank bank;//建立Bank物件
public SaveAccount(Bank bank) {
super();
this.bank = bank;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
@Override
public void run() {
// TODO Auto-generated method stub
bank.savaAccount();
}
}
DrawAccount.java
package com.demo.day9.thread;
/*
* 取款
*/
public class DrawAccount implements Runnable {
Bank bank;
public DrawAccount(Bank bank) {
super();
this.bank = bank;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
@Override
public void run() {
// TODO Auto-generated method stub
bank.drawAccouct();
}
}
Test.java
package com.demo.day9.thread;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Bank bank=new Bank("1001",1000);//建立物件bank
SaveAccount sa=new SaveAccount(bank);
DrawAccount da=new DrawAccount(bank);
//建立執行緒物件
Thread save =new Thread(sa);
Thread draw =new Thread(da);
save.run();
draw.run();
try {
draw.join();
save.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(bank);
}
}
輸出:
存款後賬戶餘額:1100
取款後賬戶餘額:900
賬戶為:1001 餘額為:900
銀行存取款問題
- 為了保證在存款或取款的時候,不允許其他執行緒進行操作
- 需要將Bank物件進行鎖定
- 使用關鍵字synchronized實現
同步
synchronized關鍵字用在
成員方法
public synchronized void saveAccount(){}
靜態方法
public static synchronized void saveAccount(){}
語句塊
synchronize (obj){.....}
執行緒間通訊
- wait()方法:中斷方法的執行,是執行緒等待
- 如果不配合notify方法使用,可能使兩個執行緒都處於等待狀態,陷入死鎖
- notify()方法:喚醒處於等待的某個執行緒,使其等待結束
- notifyAll()方法:喚醒所有處於等待的執行緒,使他們結束等待
案例要求:
- 生產者每生產一個後,消費者消費一個;
- 不能存在生產者生產一個,消費者消費兩個
- 或者生產者生產兩個,消費者消費一個
Queue.java
package com.demo.day9.thread;
public class Queue {
private int n;
boolean flag=false;//設預設flag為false。預設先生產
public synchronized int getN() {
if(!flag) {//執行等待
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("消費"+n);
flag=false;//消費完畢,再flag重新賦值為false
notifyAll();//與wait()搭配使用,喚醒所有執行緒
return n;
}
public synchronized void setN(int n) {
if(flag) {//如果容器裡有資料,flag為true,執行等待
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("生產"+n);
this.n = n;
flag=true;//生產完畢,重新另flag為true
notifyAll();//喚醒所有的執行緒
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
Producer.java
package com.demo.day9.thread;
public class Producer implements Runnable{
Queue queue;
Producer( Queue queue){
this.setQueue(queue);
}
public Queue getQueue() {
return queue;
}
public void setQueue(Queue queue) {
this.queue = queue;
}
@Override
public void run() {
// TODO Auto-generated method stub
int i=0;
while(true) {
queue.setN(i++);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Consumer.java
package com.demo.day9.thread;
public class Consumer implements Runnable {
Queue queue;
public Consumer(Queue queue) {
super();
this.queue = queue;
}
@Override
public void run() {
while(true)
{
queue.getN();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
TestQ.java
package com.demo.day9.thread;
public class TestQ {
public static void main(String[] args) {
// 建立Queue物件
Queue queue=new Queue();
//建立物件
Producer p1=new Producer(queue);
Consumer c1=new Consumer(queue);
//實現上面建立的物件
// Thread p=new Thread(p1);
// Thread c=new Thread(c1);
// p.start();
// c.start();
new Thread(new Producer(queue)).start();
new Thread(new Consumer(queue)).start();
}
}
輸出結果:
生產0
消費0
生產1
消費1
生產2
消費2
生產3
消費3
生產4
消費4
生產5
消費5
生產6....
綜合案例:
生成天氣資料,然後顯示出來
Weather.java
package com.test;
/*
* 這是一個天氣類Weather,用於溫度和溼度資料的存放和讀取
*/
public class Weather {
private int temperature;//溫度
private int humidity;//溼度
boolean flag=true;
//帶參構造
Weather(){
this.setHumidity(humidity);
this.setTemperature(temperature);
}
//生成天氣資料的方法
public synchronized void generateWeather(int temp,int hum) {
if(!flag)//如果flag=false
{
try {
wait();//如果為flag為假讓它等待
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.setHumidity(hum);
this.setTemperature(temp);
System.out.println("生成天氣資料:"+"[溫度:"+this.getTemperature()+",溼度:"+this.getHumidity()+"]");
notifyAll();//喚醒所有等待
flag=false;//重新flag賦值為false
}
//顯示天氣資料的方法
public synchronized void readWeather() {
if(flag) {//如果為真等待
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("讀取天氣資料:"+"[溫度:"+this.getTemperature()+",溼度:"+this.getHumidity()+"]");
notifyAll();//喚醒所有等待
flag=true;//重新flag賦值為false
}
public int getTemperature() {
return temperature;
}
public void setTemperature(int temperature) {
this.temperature = temperature;
}
public int getHumidity() {
return humidity;
}
public void setHumidity(int humidity) {
this.humidity = humidity;
}
}
GenerateWeather.java
package com.test;
/*
* 這個是個執行緒類,用於生成天氣資料,模擬生成100次
*/
public class GenerateWeather implements Runnable{
Weather weather;
GenerateWeather(Weather weather){
this.weather=weather;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
@Override
public void run() {
int i=1;
int temp=32;
int hum=26;
while(i<100) {
temp+=1;
hum+=1;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
weather.generateWeather(temp,hum);
i++;
}
}
}
ReadWeather.java
package com.test;
/*
* 這是一個執行緒類,用於讀取天氣資料
*/
public class ReadWeather implements Runnable {
Weather weather;
ReadWeather(Weather weather){
this.weather=weather;
}
@Override
public void run() {
// TODO Auto-generated method stub
int i=1;
while(i<100) {
weather.readWeather();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
i++;
}
}
}
WeatherTest.java
package com.test;
public class WeatherTest {
public static void main(String[] args) {
Weather wt=new Weather();
new Thread(new GenerateWeather(wt)).start();
new Thread(new ReadWeather(wt)).start();
}
}
顯示結果
生成天氣資料:[溫度:33,溼度:27]
讀取天氣資料:[溫度:33,溼度:27]
生成天氣資料:[溫度:34,溼度:28]
讀取天氣資料:[溫度:34,溼度:28]
生成天氣資料:[溫度:35,溼度:29]
讀取天氣資料:[溫度:35,溼度:29]
生成天氣資料:[溫度:36,溼度:30]
讀取天氣資料:[溫度:36,溼度:30]
生成天氣資料:[溫度:37,溼度:31]
讀取天氣資料:[溫度:37,溼度:31]
生成天氣資料:[溫度:38,溼度:32]
讀取天氣資料:[溫度:38,溼度:32]
.......
相關文章
- Java多執行緒-基礎篇Java執行緒
- 【JAVA】【面試】【基礎篇】- 執行緒、鎖Java面試執行緒
- Java 執行緒基礎Java執行緒
- 最全java多執行緒學習總結1--執行緒基礎Java執行緒
- android基礎學習-java篇day7-step3-第三節:java字串AndroidJava字串
- android基礎學習-java篇day8-step3-第四節:java集合AndroidJava
- Java 執行緒基礎,從這篇開始Java執行緒
- (一)基礎篇:速讀Java執行緒池Java執行緒
- Java執行緒池一:執行緒基礎Java執行緒
- java - 多執行緒基礎Java執行緒
- java 執行緒學習Java執行緒
- Java 多執行緒基礎(四)執行緒安全Java執行緒
- [Java基礎]虛擬執行緒Java執行緒
- Java 基礎(十四)執行緒——下Java執行緒
- Java基礎之執行緒安全Java執行緒
- Java 多執行緒基礎 - CyclicBarrierJava執行緒
- Java 多執行緒基礎(八)執行緒讓步Java執行緒
- Java多執行緒學習Java執行緒
- Java多執行緒學習(一)Java多執行緒入門Java執行緒
- Java多執行緒學習——執行緒通訊Java執行緒
- Java多執行緒學習(2)執行緒控制Java執行緒
- java基礎 關於執行緒安全Java執行緒
- JAVA_基礎多執行緒(一)Java執行緒
- Java基礎之執行緒那些事Java執行緒
- Java-基礎-執行緒入門Java執行緒
- 多執行緒學習一(多執行緒基礎)執行緒
- #大學#Java多執行緒學習02(執行緒同步)Java執行緒
- android基礎學習-java篇day10-step3-第六節:java輸入輸出流AndroidJava
- java多執行緒基礎篇(wait、notify、join、sleep、yeild方法)Java執行緒AI
- Java 多執行緒NIO學習Java執行緒
- 【java學習】ThreadPoolExecutor 執行緒池Javathread執行緒
- 程式執行緒篇——程式執行緒基礎執行緒
- Java基礎 第三節 第五課Java
- Java 多執行緒基礎(六)執行緒等待與喚醒Java執行緒
- Java執行緒篇——執行緒的開啟Java執行緒
- Java併發基礎(2)------執行緒池Java執行緒
- Java基礎之多執行緒程式設計Java執行緒程式設計
- java基礎之執行緒 認識volatileJava執行緒