天天看點

java筆試面試題---基礎部分5

48、同步和異步有何異同,在什麼情況下分别使用他們?舉例說明。

如果資料将線上程間共享。例如正在寫的資料以後可能被另一個線程讀到,或者正在讀的資料可能已經被另一個線程寫過了,那麼這些資料就是共享資料,必須進行同步存取。當應用程式在對象上調用了一個需要花費很長時間來執行的方法,并且不希望讓程式等待方法的傳回時,就應該使用異步程式設計,在很多情況下采用異步途徑往往更有效率。

50、多線程有幾種實作方法?同步有幾種實作方法?

多線程有兩種實作方法,分别是繼承Thread類與實作Runnable接口同步的實作方面有兩種,分别是synchronized,wait與notify

wait():使一個線程處于等待狀态,并且釋放所持有的對象的 lock。

sleep():使一個正在運作的線程處于睡眠狀态,是一個靜态方法,調用此方法要捕捉InterruptedException異常。

notify():喚醒一個處于等待狀态的線程,注意的是在調用此方法的時候,并不能确切的喚醒某一個等待狀态的線程,而是由 JVM 确定喚醒哪個線程,而且不是按優先級。

notityAll():喚醒所有處入等待狀态的線程,注意并不是給所有喚醒線程一個對象的鎖,而是讓它們競争。

51、啟動一個線程是用 run()還是 start()?

啟動一個線程是調用 start()方法,使線程就緒狀态,以後可以被排程為運作狀态,一個線程必須關聯一些具體的執行代碼,run()方法是該線程所關聯的執行代碼。

52、當一個線程進入一個對象的一個 synchronized方法後,其它線程是否可進入此對象的其它方法?

分幾種情況:

1.其他方法前是否加了 synchronized 關鍵字,如果沒加,則能。

2.如果這個方法内部調用了 wait,則可以進入其他 synchronized 方法。

3.如果其他個方法都加了 synchronized 關鍵字,并且内部沒有調用 wait,則不能。

4.如果其他方法是 static,它用的同步鎖是目前類的位元組碼,與非靜态的方法不能

同步,因為非靜态的方法用的是 this。

53、線程的基本概念、線程的基本狀态以及狀态之間的關系

一個程式中可以有多條執行線索同時執行,一個線程就是程式中的一條執行線索,每個線程上都關聯有要執行的代碼,即可以有多段程式代碼同時運作,每個程式至少都有一個線程,即 main 方法執行的那個線程。如果隻是一個 cpu,它怎麼能夠同時執行多段程式呢?這是從宏觀上來看的,cpu 一會執行 a 線索,一會執行 b 線索,切換時間很快,給人的感覺是 a,b 在同時執行,好比大家在同一個辦公室上網,隻有一條連結到外部網線,其實,這條網線一會為 a傳資料,一會為 b 傳資料,由于切換時間很短暫,是以,大家感覺都在同時上網。

狀态:就緒,運作,synchronize 阻塞,wait 和 sleep 挂起,結束。wait 必須在 synchronized

内部調用。

調用線程的 start 方法後線程進入就緒狀态,線程排程系統将就緒狀态的線程轉為運作狀态,遇到synchronized 語句時,由運作狀态轉為阻塞,當 synchronized 獲得鎖後,由阻塞轉為運作,在這種情況可以調用 wait 方法轉為挂起狀态,當線程關聯的代碼執行完後,線程變為結束狀态。

54、簡述 synchronized和 java.util.concurrent.locks.Lock 的異同 ?

主要相同點:Lock 能完成 synchronized 所實作的所有功能

主要不同點:Lock 有比 synchronized 更精确的線程語義和更好的性能。synchronized 會

自動釋放鎖,而 Lock 一定要求程式員手工釋放,并且必須在 finally 從句中釋放。Lock

還有更強大的功能,例如,它的 tryLock 方法可以非阻塞方式去拿鎖。

舉例說明(對下面的題用 lock 進行了改寫):

package com.huawei.interview;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

public class ThreadTest {

/**

* @param args

*/

private int j;

private Lock lock = new ReentrantLock();

public static void main(String[] args) {

// TODO Auto-generated method stub

ThreadTest tt = new ThreadTest();

for(int i=0;i<2;i++)

{

new Thread(tt.new Adder()).start();

new Thread(tt.new Subtractor()).start();

}

private class Subtractor implements Runnable

@Override

public void run() {

while(true)

/*synchronized (ThreadTest.this) {

System.out.println("j--=" + j--);

//這裡抛異常了,鎖能釋放嗎?

}*/

lock.lock();

try

}finally

lock.unlock();

private class Adder implements Runnable

System.out.println("j++=" + j++);

繼續閱讀