Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android知識回顧-----多線程

android知識回顧-----多線程

編輯:關於Android編程

1)現在有T1、T2、T3三個線程,你怎樣保證T2在T1執行完後執行,T3在T2執行完後執行?

這個線程問題通常會在第一輪或電話面試階段被問到,目的是檢測你對”join”方法是否熟悉。這個多線程問題比較簡單,可以用join方法實現。

sleep和yield有點相似都是讓步,但是讓法不一樣
sleep表示,當前線程停 一定時間後,再往下執行。把機會讓給別的線程。他不管優先級,反正哥就是讓別的先走
yield表示給同優先級或更高優先級的線程一個運行的機會。至於有沒有生效,不太確定。

join:表示等其它線程,它有一個時間參數,也可以沒有時間參數。當沒有的時候,是表示,等這個線程執行完才往下執行。
當有時間參數的時候,有兩種情況:
先設:主線程為mainThread,分線程為aThread. 三個線程類似
mainThread裡執行aThread.join(10000) ;表示mainThread等aThread執行10秒再說。但如果10秒裡,aThread最多只要執行5秒就完事,那麼,mainThread只要等5秒就會不再等了。因為aThread已經完事了。如果10秒裡aThread要10秒以上的時間才能執行完。那會怎樣呢?mainThread會不管你執行完沒完,等你10秒就不等了。哥先走一步。

package join;

public class JoinTest{
public static void main(String[] args) {
Thread t = new Thread(new MyRunable());
t.start();
try {
System.out.println("join前");
t.join(100000);
System.out.println("join後");
} catch (InterruptedException e) {
e.printStackTrace();
} }
}

class MyRunable implements Runnable {
@Override
public void run() {
try {
System.out.println("開始睡");
Thread.sleep(2000);
System.out.println("睡完");
} catch (InterruptedException e) {
e.printStackTrace();
}
}}

 


以上代碼是等了10秒,但是分線程2秒就完事,所以,2秒後主線程就開始往下走了。大家可以修改時間感受一下,記住如果join()裡沒有時間參數,表示,無限等,等它完事才往下執行,比較癡情哦。楊過才16年呢

 

 

2)在Java中Lock接口比synchronized塊的優勢是什麼?你需要實現一個高效的緩存,它允許多個用戶讀,但只允許一個用戶寫,以此來保持它的完整性,你會怎樣去實現它?

lock接口在多線程和並發編程中最大的優勢是它們為讀和寫分別提供了鎖,它能滿足你寫像ConcurrentHashMap這樣的高性能數據結構和有條件的阻塞。Java線程面試的問題越來越會根據面試者的回答來提問。我強烈建議在你去參加多線程的面試之前認真讀一下Locks,因為當前其大量用於構建電子交易終統的客戶端緩存和交易連接空間。

3)在java中wait和sleep方法的不同?

通常會在電話面試中經常被問到的Java線程面試問題。最大的不同是在等待時wait會釋放鎖,而sleep一直持有鎖。Wait通常被用於線程間交互,sleep通常被用於暫停執行。

對於sleep()方法,我們首先要知道該方法是屬於Thread類中的。而wait()方法,則是屬於Object類中的。

sleep()方法導致了程序暫停執行指定的時間,讓出cpu該其他線程,但是他的監控狀態依然保持者,當指定的時間到了又會自動恢復運行狀態。

在調用sleep()方法的過程中,線程不會釋放對象鎖。

而當調用wait()方法的時候,線程會放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象調用notify()方法後本線程才進入對象鎖定池准備

獲取對象鎖進入運行狀態。

什麼意思呢?

舉個列子說明:

 1 /**
 2  * 
 3  */
 4 package com.b510.test;
 5 
 6 /**
 7  * java中的sleep()和wait()的區別
 8  * @author Hongten
 9  * @date 2013-12-10
10  */
11 public class TestD {
12 
13     public static void main(String[] args) {
14         new Thread(new Thread1()).start();
15         try {
16             Thread.sleep(5000);
17         } catch (Exception e) {
18             e.printStackTrace();
19         }
20         new Thread(new Thread2()).start();
21     }
22     
23     private static class Thread1 implements Runnable{
24         @Override
25         public void run(){
26             synchronized (TestD.class) {
27             System.out.println("enter thread1...");    
28             System.out.println("thread1 is waiting...");
29             try {
30                 //調用wait()方法,線程會放棄對象鎖,進入等待此對象的等待鎖定池
31                 TestD.class.wait();
32             } catch (Exception e) {
33                 e.printStackTrace();
34             }
35             System.out.println("thread1 is going on ....");
36             System.out.println("thread1 is over!!!");
37             }
38         }
39     }
40     
41     private static class Thread2 implements Runnable{
42         @Override
43         public void run(){
44             synchronized (TestD.class) {
45                 System.out.println("enter thread2....");
46                 System.out.println("thread2 is sleep....");
47                 //只有針對此對象調用notify()方法後本線程才進入對象鎖定池准備獲取對象鎖進入運行狀態。
48                 TestD.class.notify();
49                 //==================
50                 //區別
51                 //如果我們把代碼:TestD.class.notify();給注釋掉,即TestD.class調用了wait()方法,但是沒有調用notify()
52                 //方法,則線程永遠處於掛起狀態。
53                 try {
54                     //sleep()方法導致了程序暫停執行指定的時間,讓出cpu該其他線程,
55                     //但是他的監控狀態依然保持者,當指定的時間到了又會自動恢復運行狀態。
56                     //在調用sleep()方法的過程中,線程不會釋放對象鎖。
57                     Thread.sleep(5000);
58                 } catch (Exception e) {
59                     e.printStackTrace();
60                 }
61                 System.out.println("thread2 is going on....");
62                 System.out.println("thread2 is over!!!");
63             }
64         }
65     }
66 }

運行效果:

enter thread1...
thread1 is waiting...
enter thread2....
thread2 is sleep....
thread2 is going on....
thread2 is over!!!
thread1 is going on ....
thread1 is over!!!

如果注釋掉代碼:

1 TestD.class.notify();

運行效果:

enter thread1...
thread1 is waiting...
enter thread2....
thread2 is sleep....
thread2 is going on....
thread2 is over!!!

且程序一直處於掛起狀態。

 

4)用Java實現阻塞隊列。

這是一個相對艱難的多線程面試問題,它能達到很多的目的。第一,它可以檢測侯選者是否能實際的用Java線程寫程序;第二,可以檢測侯選者對並發場景的理解,並且你可以根據這個問很多問題。如果他用wait()和notify()方法來實現阻塞隊列,你可以要求他用最新的Java 5中的並發類來再寫一次。

5)用Java寫代碼來解決生產者——消費者問題。

與上面的問題很類似,但這個問題更經典,有些時候面試都會問下面的問題。在Java中怎麼解決生產者——消費者問題,當然有很多解決方法,我已經分享了一種用阻塞隊列實現的方法。有些時候他們甚至會問怎麼實現哲學家進餐問題。

6)用Java編程一個會導致死鎖的程序,你將怎麼解決?

這是我最喜歡的Java線程面試問題,因為即使死鎖問題在寫多線程並發程序時非常普遍,但是很多侯選者並不能寫deadlock free code(無死鎖代碼?),他們很掙扎。只要告訴他們,你有N個資源和N個線程,並且你需要所有的資源來完成一個操作。為了簡單這裡的n可以替換為2,越大的數據會使問題看起來更復雜。通過避免Java中的死鎖來得到關於死鎖的更多信息。

7)什麼是原子操作,Java中的原子操作是什麼?

非常簡單的java線程面試問題,接下來的問題是你需要同步一個原子操作。

8)Java中的volatile關鍵是什麼作用?怎樣使用它?在Java中它跟synchronized方法有什麼不同?

自從Java 5和Java內存模型改變以後,基於volatile關鍵字的線程問題越來越流行。應該准備好回答關於volatile變量怎樣在並發環境中確保可見性、順序性和一致性。

9)什麼是競爭條件?你怎樣發現和解決競爭?

這是一道出現在多線程面試的高級階段的問題。大多數的面試官會問最近你遇到的競爭條件,以及你是怎麼解決的。有些時間他們會寫簡單的代碼,然後讓你檢測出代碼的競爭條件。可以參考我之前發布的關於Java競爭條件的文章。在我看來這是最好的java線程面試問題之一,它可以確切的檢測候選者解決競爭條件的經驗,orwriting code which is free of data race or any otherrace condition。關於這方面最好的書是《Concurrency practices in Java》。

10)你將如何使用thread dump?你將如何分析Thread dump?

在UNIX中你可以使用kill -3,然後thread dump將會打印日志,在windows中你可以使用”CTRL+Break”。非常簡單和專業的線程面試問題,但是如果他問你怎樣分析它,就會很棘手。

11)為什麼我們調用start()方法時會執行run()方法,為什麼我們不能直接調用run()方法?

這是另一個非常經典的java多線程面試問題。這也是我剛開始寫線程程序時候的困惑。現在這個問題通常在電話面試或者是在初中級Java面試的第一輪被問到。這個問題的回答應該是這樣的,當你調用start()方法時你將創建新的線程,並且執行在run()方法裡的代碼。但是如果你直接調用run()方法,它不會創建新的線程也不會執行調用線程的代碼。閱讀我之前寫的《start與run方法的區別》這篇文章來獲得更多信息。

12)Java中你怎樣喚醒一個阻塞的線程?

這是個關於線程和阻塞的棘手的問題,它有很多解決方法。如果線程遇到了IO阻塞,我並且不認為有一種方法可以中止線程。如果線程因為調用wait()、sleep()、或者join()方法而導致的阻塞,你可以中斷線程,並且通過拋出InterruptedException來喚醒它。我之前寫的《How to deal with blocking methods in java》有很多關於處理線程阻塞的信息。

13)在Java中CycliBarriar和CountdownLatch有什麼區別?

這個線程問題主要用來檢測你是否熟悉JDK5中的並發包。這兩個的區別是CyclicBarrier可以重復使用已經通過的障礙,而CountdownLatch不能重復使用。

14)什麼是不可變對象,它對寫並發應用有什麼幫助?

另一個多線程經典面試問題,並不直接跟線程有關,但間接幫助很多。這個java面試問題可以變的非常棘手,如果他要求你寫一個不可變對象,或者問你為什麼String是不可變的。

15)你在多線程環境中遇到的共同的問題是什麼?你是怎麼解決它的?

多線程和並發程序中常遇到的有Memory-interface、競爭條件、死鎖、活鎖和饑餓。問題是沒有止境的,如果你弄錯了,將很難發現和調試。這是大多數基於面試的,而不是基於實際應用的Java線程問題。

補充的其它幾個問題:

1)在java中綠色線程和本地線程區別?

2)線程與進程的區別?

3)什麼是多線程中的上下文切換?

4)死鎖與活鎖的區別,死鎖與餡餅的區別?

5)Java中用到的線程調度算法是什麼?

6)在Java中什麼是線程調度?

7)在線程中你怎麼處理不可捕捉異常?

8)什麼是線程組,為什麼在Java中不推薦使用?

9)為什麼使用Executor框架比使用應用創建和管理線程好?

10)在Java中Executor和Executors的區別?

11)如何在Windows和Linux上查找哪個線程使用的CPU時間最長?

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved