1. 程式人生 > >java執行緒的理解

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();
	}

}

執行結果: