Android項目中的一個需求:通過線程讀取文件內容,并且可以控制線程的開始、暫停、繼續,來控制讀文件。在此記錄下。
直接在主線程中,通過wait、notify、notifyAll去控制讀文件的線程(子線程),報錯:java.lang.IllegalMonitorStateException。
需要注意的幾個問題:
- 任何一個時刻,對象的控制權(monitor)只能被一個線程擁有。
- 無論是執行對象的wait、notify還是notifyAll方法,必須保證當前運行的線程取得了該對象的控制權(monitor)。
- 如果在沒有控制權的線程里執行對象的以上三種方法,就會報錯java.lang.IllegalMonitorStateException。
- JVM基于多線程,默認情況下不能保證運行時線程的時序性。
線程取得控制權的3種方法:
- 執行對象的某個同步實例方法。
- 執行對象對應類的同步靜態方法。
- 執行對該對象加同步鎖的同步塊。
這里將開始、暫停、繼續封裝在線程類中,直接調用該實例的方法就行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
public class ReadThread implements Runnable{ public Thread t; private String threadName; boolean suspended= false ; public ReadThread(String threadName){ this .threadName=threadName; System.out.println( "Creating " + threadName ); } public void run() { for ( int i = 10 ; i > 0 ; i--) { System.out.println( "Thread: " + threadName + ", " + i); // Let the thread sleep for a while. try { Thread.sleep( 300 ); synchronized ( this ) { while (suspended) { wait(); } } } catch (InterruptedException e) { System.out.println( "Thread " + threadName + " interrupted." ); e.printStackTrace(); } System.out.println( "Thread " + threadName + " exiting." ); } } /** * 開始 */ public void start(){ System.out.println( "Starting " + threadName ); if (t== null ){ t= new Thread( this , threadName); t.start(); } } /** * 暫停 */ void suspend(){ suspended = true ; } /** * 繼續 */ synchronized void resume(){ suspended = false ; notify(); } } |
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持服務器之家!
原文鏈接:http://www.cnblogs.com/Joanna-Yan/p/5142348.html