1. 程式人生 > >Java經典面試題總結(六)

Java經典面試題總結(六)

本次的面試題:多執行緒知識的面試解答題。

1. 有T1、T2、T3三個執行緒,如何怎樣保證T2在T1執行完後執行,T3在T2執行完後執行?


答:使用join方法。

join方法的功能是使非同步執行的執行緒變成同步執行。即呼叫執行緒例項的start方法後,該方法會立即返回,如果呼叫start方法後,需要使用一個由這個執行緒計算得到的值,就必須使用join方法。如果不使用join方法,就不能保證當執行到start方法後面的某條語句時,這個執行緒一定會執行完。而使用join方法後,直到這個執行緒退出,程式才會往下執行。

2.Java中的Lock介面,比起synchronized,優勢在哪裡?

如果需要實現一個高效的快取,它允許多個使用者讀,但只允許一個使用者寫,以此來保持它的完整性,如何實現?

Lock介面最大的優勢是為讀和寫分別提供了鎖。

讀寫鎖ReadWriteLock擁有更加強大的功能,它可細分為讀鎖和解鎖。

讀鎖可以允許多個進行讀操作的執行緒同時進入,但不允許寫程序進入;寫鎖只允許一個寫程序進入,在這期間任何程序都不能再進入。(完全符合題目中允許多個使用者讀和一個使用者寫的條件)

要注意的是每個讀寫鎖都有掛鎖和解鎖,最好將每一對掛鎖和解鎖操作都用try、finally來套入中間的程式碼,這樣就會防止因異常的發生而造成死鎖得情況。

下面是一個示例程式:

```

import java.util.Random;

import java.util.concurrent.locks.*;

public class ReadWriteLockTest {

 public static void main(String[] args) {

  final TheData myData=new TheData();  //這是各執行緒的共享資料

  for(int i=0;i<3;i++){ //開啟3個讀執行緒

   new Thread(new Runnable(){

    @Override

    public void run() {

     while(true){

      myData.get();

     }

    }

   }).start();

  }

  for(int i=0;i<3;i++){ //開啟3個寫執行緒

   new Thread(new Runnable(){

    @Override

    public void run() {

     while(true){

      myData.put(new Random().nextInt(10000));

     }

    }

   }).start();

  }

 }

}

class TheData{

 private Object data=null;

 private ReadWriteLock rwl=new ReentrantReadWriteLock();

 public void get(){

  rwl.readLock().lock();  //讀鎖開啟,讀執行緒均可進入

  try { //用try finally來防止因異常而造成的死鎖

   System.out.println(Thread.currentThread().getName()+"is ready to read");

   Thread.sleep(new Random().nextInt(100));

   System.out.println(Thread.currentThread().getName()+"have read date"+data);

  } catch (InterruptedException e) {

   e.printStackTrace();

  } finally{

   rwl.readLock().unlock(); //讀鎖解鎖

  }

 }

 public void put(Object data){

  rwl.writeLock().lock();  //寫鎖開啟,這時只有一個寫執行緒進入

  try {

   System.out.println(Thread.currentThread().getName()+"is ready to write");

   Thread.sleep(new Random().nextInt(100));

   this.data=data;

   System.out.println(Thread.currentThread().getName()+"have write date"+data);

  } catch (InterruptedException e) {

   e.printStackTrace();

  } finally{

   rwl.writeLock().unlock(); //寫鎖解鎖

  }

 }

}


```

3. java中wait和sleep方法有何不同?

很大的不同是在等待時wait會釋放鎖,而sleep一直持有鎖。Wait通常被用於執行緒間互動,sleep通常被用於暫停執行。

其它不同有:

- sleep是Thread類的靜態方法,wait是Object方法。

- wait,notify和notifyAll只能在同步控制方法或者同步控制塊裡面使用,而sleep可以在任何地方使用

- sleep必須捕獲異常,而wait,notify和notifyAll不需要捕獲異常。