java執行緒的理解
一 、執行緒的理解
1. 執行緒是系統排程中最小的單位,因為其擁有比程序更小的資源消耗,因此,在進行同類事情,需要進行互動的通訊時,都採用執行緒來進行處理。就像QQ聊天,開啟一個聊 天 視窗 就是一個執行緒。
2. 多執行緒是否就沒有存在的意義了呢?答案當然不是的。多執行緒還是有存在的價值的,我們在寫輸入流輸出流,寫網路程式等等的時候,都會出現阻塞的情況,如果說,我們 不使用多執行緒的話,從A中讀資料出來的時候,A因為沒有準備好,而整個程式阻塞了,其他的任何事情都沒法進行。如果採用多執行緒的話,你就不用擔心這個問題了。還舉個例 子:遊戲中,如果A角色和B角色採用同一個執行緒來處理的話,那麼,很有可能就會出現只會響應A角色的操作,而B角色就始終被佔用了的情況,這樣,玩起來肯定就沒勁了。
因此,執行緒是有用的,但也不是隨便亂用,亂用的話,可能造成效能的低下,它是有一點的適用範圍的,一般我認為:需要響應多個人的事情,從設計上需要考慮同時做一些 事情(這些事情很多情況下可能一點關係都沒有,也有可能有一些關係的)。
3. 使用多執行緒的時候,如果某些執行緒之間涉及到資源共享、互相通訊等等問題的時候,一定得注意執行緒安全的問題,根據情況看是不是需要使用synchronized關鍵字。
二、java中使用執行緒
1、建立執行緒
eg1:繼承Thread
class MyThread extends Thread{
@Override
public void run() {
//code
}
}
啟動執行緒方法:new MyThread().start();
eg2:實現Runnable介面
class MyRunnable implements Runnable {
@Override
public void run() {
//code
}
}
啟動執行緒方法:new Thread(new MyRunnable()).start();
2、設定執行緒優先順序
Thread t = new Thread(myRunnable);
t.setPriority(Thread.MAX_PRIORITY);
t.start();
3.join方法:假如你在A執行緒中呼叫了B執行緒的join方法B.join();,這時B執行緒繼續執行,A執行緒停止(進入阻塞狀態)。等B執行完畢A再繼續執行。
sleep方法:執行緒中呼叫sleep方法後,本執行緒停止(進入阻塞狀態),執行權交給其他執行緒。
yield方法:執行緒中呼叫yield方法後本執行緒並不停止,執行權由本執行緒和優先順序不低於本執行緒的執行緒來搶。(不一定優先順序高的能先搶到,只是優先順序高的搶到的時間長)
4、執行緒同步synchronized
5、wait、notify、notifyAll的用法
wait方法:當前執行緒轉入阻塞狀態,讓出cpu的控制權,解除鎖定。
notify方法:喚醒因為wait()進入阻塞狀態的其中一個執行緒。
notifyAll方法: 喚醒因為wait()進入阻塞狀態的所有執行緒。
這三個方法都必須用synchronized塊來包裝,而且必須是同一把鎖,不然會丟擲java.lang.IllegalMonitorStateException異常。
6、結束執行緒(修改標示符flag為false來終止執行緒的執行)
三、下面是個小例子:
模擬銀行存款情況:
Bank.java
package ytu.edu.com;
public class Bank implements Runnable{
int money=200;
public void setMoney(int n){
money=n;
}
public void run(){
if(Thread.currentThread().getName().equals("會計")){
saveOrTake(300);
}
else if (Thread.currentThread().getName().equals("出納")){
saveOrTake(150);
}
}
public synchronized void saveOrTake(int amount){
if(Thread.currentThread().getName().equals("會計")){
for(int i=0;i<3;i++){
money=money+amount/3;
System.out.println(Thread.currentThread().getName()+"存入"+amount/3+"賬戶上有"+money+"休息一會在存。。。");
try{
Thread.sleep(1000);
}catch(InterruptedException e){}
}
}
else if (Thread.currentThread().getName().equals("出納")){
for(int i=0;i<3;i++){
money=money-amount/3;
System.out.println(Thread.currentThread().getName()+"存入"+amount/3+"賬戶上有"+money+"休息一會在存。。。");
try {
Thread.sleep(1000);
}catch(InterruptedException e){}
}
}
}
}
測試類 test.java
package ytu.edu.com;
public class test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Bank bank=new Bank();
bank.setMoney(200);
Thread accountant,cashier;
accountant=new Thread(bank);
cashier=new Thread(bank);
accountant.setName("會計");
cashier.setName("出納");
accountant.start();
cashier.start();
}
}
執行結果: