久久亚洲精品成人_国产精品欧美综合亚洲_亚洲va天堂va欧美ⅴa在线_91色视频在线观看_久久影院亚洲_一级黄色片播放_日韩av在线一区_精品一区二区在线看_老头吃奶性行交视频_日韩免费高清视频_天天操天天爽天天干_日本欧美在线视频

首頁 > 編程 > Java > 正文

java線程阻塞中斷與LockSupport使用介紹

2019-11-26 16:16:39
字體:
供稿:網(wǎng)友
上周五和周末,工作忙里偷閑,在看java cocurrent中也順便再溫故了一下Thread.interrupt和java 5之后的LockSupport的實現(xiàn)。
在介紹之前,先拋幾個問題。
Thread.interrupt()方法和InterruptedException異常的關(guān)系?是由interrupt觸發(fā)產(chǎn)生了InterruptedException異常?
Thread.interrupt()會中斷線程什么狀態(tài)的工作? RUNNING or BLOCKING?
一般Thread編程需要關(guān)注interrupt中斷不?一般怎么處理?可以用來做什么?
LockSupport.park()和unpark(),與object.wait()和notify()的區(qū)別?
LockSupport.park(Object blocker)傳遞的blocker對象做什么用?
LockSupport能響應(yīng)Thread.interrupt()事件不?會拋出InterruptedException異常?
Thread.interrupt()處理是否有對應(yīng)的回調(diào)函數(shù)?類似于鉤子調(diào)用?
如果你都都能很明確的答上來了,說明你已經(jīng)完全懂Thread.interrupt,可以不用往下看那了。
那如果不清楚的,帶著這幾個問題,一起來梳理下。
Thread的interrupt處理的幾個方法:
public void interrupt() : 執(zhí)行線程interrupt事件
public boolean isInterrupted() : 檢查當前線程是否處于interrupt
public static boolean interrupted() : check當前線程是否處于interrupt,并重置interrupt信息。類似于resetAndGet()
理解:
1. 每個線程都有一個interrupt status標志位,用于表明當前線程是否處于中斷狀態(tài)
2. 一般調(diào)用Thread.interrupt()會有兩種處理方式
遇到一個低優(yōu)先級的block狀態(tài)時,比如object.wait(),object.sleep(),object.join()。它會立馬觸發(fā)一個unblock解除阻塞,并throw一個InterruptedException。
其他情況,Thread.interrupt()僅僅只是更新了status標志位。然后你的工作線程通過Thread.isInterrrupted()進行檢查,可以做相應(yīng)的處理,比如也throw InterruptedException或者是清理狀態(tài),取消task等。
在interrupt javadoc中描述:
 
最佳實踐
IBM上有篇文章寫的挺不錯。Java theory and practice: Dealing with InterruptedException , 里面提到了Interrupt處理的幾條最佳實踐。
Don't swallow interrupts (別吃掉Interrupt,一般是兩種處理: 繼續(xù)throw InterruptedException異常。 另一種就是繼續(xù)設(shè)置Thread.interupt()異常標志位,讓更上一層去進行相應(yīng)處理。
復(fù)制代碼 代碼如下:

public class TaskRunner implements Runnable {
private BlockingQueue<Task> queue;
public TaskRunner(BlockingQueue<Task> queue) {
this.queue = queue;
}
public void run() {
try {
while (true) {
Task task = queue.take(10, TimeUnit.SECONDS);
task.execute();
}
}
catch (InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();
}
}
}

復(fù)制代碼 代碼如下:

public class TaskRunner implements Runnable {
private BlockingQueue<Task> queue;
public TaskRunner(BlockingQueue<Task> queue) {
this.queue = queue;
}
public void run() {
try {
while (true) {
Task task = queue.take(10, TimeUnit.SECONDS);
task.execute();
}
}
catch (InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();
}
}
}

Implementing cancelable tasks with Interrupt (使用Thread.interrupt()來設(shè)計和支持可被cancel的task)
復(fù)制代碼 代碼如下:

public class PrimeProducer extends Thread {
private final BlockingQueue<BigInteger> queue;
PrimeProducer(BlockingQueue<BigInteger> queue) {
this.queue = queue;
}
public void run() {
try {
BigInteger p = BigInteger.ONE;
while (!Thread.currentThread().isInterrupted())
queue.put(p = p.nextProbablePrime());
} catch (InterruptedException consumed) {
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); } // 發(fā)起中斷
}<SPAN style="WHITE-SPACE: normal"> </SPAN>

復(fù)制代碼 代碼如下:

public class PrimeProducer extends Thread {
private final BlockingQueue<BigInteger> queue;
PrimeProducer(BlockingQueue<BigInteger> queue) {
this.queue = queue;
}
public void run() {
try {
BigInteger p = BigInteger.ONE;
while (!Thread.currentThread().isInterrupted())
queue.put(p = p.nextProbablePrime());
} catch (InterruptedException consumed) {
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); } // 發(fā)起中斷
}<SPAN style="WHITE-SPACE: normal"> </SPAN>

注冊Interrupt處理事件(非正常用法)
一般正常的task設(shè)計用來處理cancel,都是采用主動輪詢的方式檢查Thread.isInterrupt(),對業(yè)務(wù)本身存在一定的嵌入性,還有就是存在延遲,你得等到下一個檢查點(誰知道下一個檢查點是在什么時候,特別是進行一個socket.read時,遇到過一個HttpClient超時的問題)。
來看一下,主動拋出InterruptedException異常的實現(xiàn),借鑒于InterruptibleChannel的設(shè)計,比較取巧。
復(fù)制代碼 代碼如下:

interface InterruptAble { // 定義可中斷的接口
public void interrupt() throws InterruptedException;
}
abstract class InterruptSupport implements InterruptAble {
private volatile boolean interrupted = false;
private Interruptible interruptor = new Interruptible() {
public void interrupt() {
interrupted = true;
InterruptSupport.this.interrupt(); // 位置3
}
};
public final boolean execute() throws InterruptedException {
try {
blockedOn(interruptor); // 位置1
if (Thread.currentThread().isInterrupted()) { // 立馬被interrupted
interruptor.interrupt();
}
// 執(zhí)行業(yè)務(wù)代碼
bussiness();
} finally {
blockedOn(null); // 位置2
}
return interrupted;
}
public abstract void bussiness() ;
public abstract void interrupt();
// -- sun.misc.SharedSecrets --
static void blockedOn(Interruptible intr) { // package-private
sun.misc.SharedSecrets.getJavaLangAccess().blockedOn(Thread.currentThread(), intr);
}
}

復(fù)制代碼 代碼如下:

interface InterruptAble { // 定義可中斷的接口
public void interrupt() throws InterruptedException;
}
abstract class InterruptSupport implements InterruptAble {
private volatile boolean interrupted = false;
private Interruptible interruptor = new Interruptible() {
public void interrupt() {
interrupted = true;
InterruptSupport.this.interrupt(); // 位置3
}
};
public final boolean execute() throws InterruptedException {
try {
blockedOn(interruptor); // 位置1
if (Thread.currentThread().isInterrupted()) { // 立馬被interrupted
interruptor.interrupt();
}
// 執(zhí)行業(yè)務(wù)代碼
bussiness();
} finally {
blockedOn(null); // 位置2
}
return interrupted;
}
public abstract void bussiness() ;
public abstract void interrupt();
// -- sun.misc.SharedSecrets --
static void blockedOn(Interruptible intr) { // package-private
sun.misc.SharedSecrets.getJavaLangAccess().blockedOn(Thread.currentThread(), intr);
}
}

代碼說明,幾個取巧的點:
位置1:利用sun提供的blockedOn方法,綁定對應(yīng)的Interruptible事件處理鉤子到指定的Thread上。
位置2:執(zhí)行完代碼后,清空鉤子。避免使用連接池時,對下一個Thread處理事件的影響。
位置3:定義了Interruptible事件鉤子的處理方法,回調(diào)InterruptSupport.this.interrupt()方法,子類可以集成實現(xiàn)自己的業(yè)務(wù)邏輯,比如sock流關(guān)閉等等。
使用:
復(fù)制代碼 代碼如下:

class InterruptRead extends InterruptSupport {
private FileInputStream in;
@Override
public void bussiness() {
File file = new File("/dev/urandom"); // 讀取linux黑洞,永遠讀不完
try {
in = new FileInputStream(file);
byte[] bytes = new byte[1024];
while (in.read(bytes, 0, 1024) > 0) {
// Thread.sleep(100);
// if (Thread.interrupted()) {// 以前的Interrupt檢查方式
// throw new InterruptedException("");
// }
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public FileInputStream getIn() {
return in;
}
@Override
public void interrupt() {
try {
in.getChannel().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) throws Exception {
final InterruptRead test = new InterruptRead();
Thread t = new Thread() {
@Override
public void run() {
long start = System.currentTimeMillis();
try {
System.out.println("InterruptRead start!");
test.execute();
} catch (InterruptedException e) {
System.out.println("InterruptRead end! cost time : " + (System.currentTimeMillis() - start));
e.printStackTrace();
}
}
};
t.start();
// 先讓Read執(zhí)行3秒
Thread.sleep(3000);
// 發(fā)出interrupt中斷
t.interrupt();
}

復(fù)制代碼 代碼如下:

class InterruptRead extends InterruptSupport {
private FileInputStream in;
@Override
public void bussiness() {
File file = new File("/dev/urandom"); // 讀取linux黑洞,永遠讀不完
try {
in = new FileInputStream(file);
byte[] bytes = new byte[1024];
while (in.read(bytes, 0, 1024) > 0) {
// Thread.sleep(100);
// if (Thread.interrupted()) {// 以前的Interrupt檢查方式
// throw new InterruptedException("");
// }
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public FileInputStream getIn() {
return in;
}
@Override
public void interrupt() {
try {
in.getChannel().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) throws Exception {
final InterruptRead test = new InterruptRead();
Thread t = new Thread() {
@Override
public void run() {
long start = System.currentTimeMillis();
try {
System.out.println("InterruptRead start!");
test.execute();
} catch (InterruptedException e) {
System.out.println("InterruptRead end! cost time : " + (System.currentTimeMillis() - start));
e.printStackTrace();
}
}
};
t.start();
// 先讓Read執(zhí)行3秒
Thread.sleep(3000);
// 發(fā)出interrupt中斷
t.interrupt();
}

jdk源碼介紹:
1. sun提供的鉤子可以查看System的相關(guān)代碼, line : 1125
復(fù)制代碼 代碼如下:

sun.misc.SharedSecrets.setJavaLangAccess(new sun.misc.JavaLangAccess(){
public sun.reflect.ConstantPool getConstantPool(Class klass) {
return klass.getConstantPool();
}
public void setAnnotationType(Class klass, AnnotationType type) {
klass.setAnnotationType(type);
}
public AnnotationType getAnnotationType(Class klass) {
return klass.getAnnotationType();
}
public <E extends Enum<E>>
E[] getEnumConstantsShared(Class<E> klass) {
return klass.getEnumConstantsShared();
}
public void blockedOn(Thread t, Interruptible b) {
t.blockedOn(b);
}
});

復(fù)制代碼 代碼如下:

sun.misc.SharedSecrets.setJavaLangAccess(new sun.misc.JavaLangAccess(){
public sun.reflect.ConstantPool getConstantPool(Class klass) {
return klass.getConstantPool();
}
public void setAnnotationType(Class klass, AnnotationType type) {
klass.setAnnotationType(type);
}
public AnnotationType getAnnotationType(Class klass) {
return klass.getAnnotationType();
}
public <E extends Enum<E>>
E[] getEnumConstantsShared(Class<E> klass) {
return klass.getEnumConstantsShared();
}
public void blockedOn(Thread t, Interruptible b) {
t.blockedOn(b);
}
});

2. Thread.interrupt()
復(fù)制代碼 代碼如下:

public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt(); //回調(diào)鉤子
return;
}
}
interrupt0();
}

復(fù)制代碼 代碼如下:

public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt(); //回調(diào)鉤子
return;
}
}
interrupt0();
}

更多
更多關(guān)于Thread.stop,suspend,resume,interrupt的使用注意點,可以看一下sun的文檔,比如http://download.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
最后來解答一下之前的幾個問題:
問題1: Thread.interrupt()方法和InterruptedException異常的關(guān)系?是由interrupt觸發(fā)產(chǎn)生了InterruptedException異常?
答: Thread.interrupt()只是在Object.wait() .Object.join(), Object.sleep()幾個方法會主動拋出InterruptedException異常。而在其他的的block常見,只是通過設(shè)置了Thread的一個標志位信息,需要程序自我進行處理。
復(fù)制代碼 代碼如下:

if (Thread.interrupted()) // Clears interrupted status!
throw new InterruptedException();

復(fù)制代碼 代碼如下:

if (Thread.interrupted()) // Clears interrupted status!
throw new InterruptedException();

問題2:Thread.interrupt()會中斷線程什么狀態(tài)的工作? RUNNING or BLOCKING?
答:Thread.interrupt設(shè)計的目的主要是用于處理線程處于block狀態(tài),比如wait(),sleep()狀態(tài)就是個例子。但可以在程序設(shè)計時為支持task cancel,同樣可以支持RUNNING狀態(tài)。比如Object.join()和一些支持interrupt的一些nio channel設(shè)計。
問題3: 一般Thread編程需要關(guān)注interrupt中斷不?一般怎么處理?可以用來做什么?
答: interrupt用途: unBlock操作,支持任務(wù)cancel, 數(shù)據(jù)清理等。
問題4: LockSupport.park()和unpark(),與object.wait()和notify()的區(qū)別?
答:
1. 面向的主體不一樣。LockSuport主要是針對Thread進進行阻塞處理,可以指定阻塞隊列的目標對象,每次可以指定具體的線程喚醒。Object.wait()是以對象為緯度,阻塞當前的線程和喚醒單個(隨機)或者所有線程。
2. 實現(xiàn)機制不同。雖然LockSuport可以指定monitor的object對象,但和object.wait(),兩者的阻塞隊列并不交叉??梢钥聪聹y試例子。object.notifyAll()不能喚醒LockSupport的阻塞Thread.
問題5: LockSupport.park(Object blocker)傳遞的blocker對象做什么用?
答: 對應(yīng)的blcoker會記錄在Thread的一個parkBlocker屬性中,通過jstack命令可以非常方便的監(jiān)控具體的阻塞對象.
復(fù)制代碼 代碼如下:

public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker); // 設(shè)置Thread.parkBlocker屬性的值
unsafe.park(false, 0L);
setBlocker(t, null); // 清除Thread.parkBlocker屬性的值
}

復(fù)制代碼 代碼如下:

public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker); // 設(shè)置Thread.parkBlocker屬性的值
unsafe.park(false, 0L);
setBlocker(t, null); // 清除Thread.parkBlocker屬性的值
}

具體LockSupport的javadoc描述也比較清楚,可以看下:
 
問題6: LockSupport能響應(yīng)Thread.interrupt()事件不?會拋出InterruptedException異常?
答:能響應(yīng)interrupt事件,但不會拋出InterruptedException異常。針對LockSupport對Thread.interrupte支持,也先看一下javadoc中的描述:
 
相關(guān)測試代碼
復(fù)制代碼 代碼如下:

package com.agapple.cocurrent;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
public class LockSupportTest {
private static LockSupportTest blocker = new LockSupportTest();
public static void main(String args[]) throws Exception {
lockSupportTest();
parkTest();
interruptParkTest();
interruptSleepTest();
interruptWaitTest();
}
/**
* LockSupport.park對象后,嘗試獲取Thread.blocker對象,調(diào)用其single喚醒
*
* @throws Exception
*/
private static void lockSupportTest() throws Exception {
Thread t = doTest(new TestCallBack() {
@Override
public void callback() throws Exception {
// 嘗試sleep 5s
System.out.println("blocker");
LockSupport.park(blocker);
System.out.println("wakeup now!");
}
@Override
public String getName() {
return "lockSupportTest";
}
});
t.start(); // 啟動讀取線程
Thread.sleep(150);
synchronized (blocker) {
Field field = Thread.class.getDeclaredField("parkBlocker");
field.setAccessible(true);
Object fBlocker = field.get(t);
System.out.println(blocker == fBlocker);
Thread.sleep(100);
System.out.println("notifyAll");
blocker.notifyAll();
}
}
/**
* 嘗試去中斷一個object.wait(),會拋出對應(yīng)的InterruptedException異常
*
* @throws InterruptedException
*/
private static void interruptWaitTest() throws InterruptedException {
final Object obj = new Object();
Thread t = doTest(new TestCallBack() {
@Override
public void callback() throws Exception {
// 嘗試sleep 5s
obj.wait();
System.out.println("wakeup now!");
}
@Override
public String getName() {
return "interruptWaitTest";
}
});
t.start(); // 啟動讀取線程
Thread.sleep(2000);
t.interrupt(); // 檢查下在park時,是否響應(yīng)中斷
}
/**
* 嘗試去中斷一個Thread.sleep(),會拋出對應(yīng)的InterruptedException異常
*
* @throws InterruptedException
*/
private static void interruptSleepTest() throws InterruptedException {
Thread t = doTest(new TestCallBack() {
@Override
public void callback() throws Exception {
// 嘗試sleep 5s
Thread.sleep(5000);
System.out.println("wakeup now!");
}
@Override
public String getName() {
return "interruptSleepTest";
}
});
t.start(); // 啟動讀取線程
Thread.sleep(2000);
t.interrupt(); // 檢查下在park時,是否響應(yīng)中斷
}
/**
* 嘗試去中斷一個LockSupport.park(),會有響應(yīng)但不會拋出InterruptedException異常
*
* @throws InterruptedException
*/
private static void interruptParkTest() throws InterruptedException {
Thread t = doTest(new TestCallBack() {
@Override
public void callback() {
// 嘗試去park 自己線程
LockSupport.parkNanos(blocker, TimeUnit.SECONDS.toNanos(5));
System.out.println("wakeup now!");
}
@Override
public String getName() {
return "interruptParkTest";
}
});
t.start(); // 啟動讀取線程
Thread.sleep(2000);
t.interrupt(); // 檢查下在park時,是否響應(yīng)中斷
}
/**
* 嘗試去中斷一個LockSupport.unPark(),會有響應(yīng)
*
* @throws InterruptedException
*/
private static void parkTest() throws InterruptedException {
Thread t = doTest(new TestCallBack() {
@Override
public void callback() {
// 嘗試去park 自己線程
LockSupport.park(blocker);
System.out.println("wakeup now!");
}
@Override
public String getName() {
return "parkTest";
}
});
t.start(); // 啟動讀取線程
Thread.sleep(2000);
LockSupport.unpark(t);
t.interrupt();
}
public static Thread doTest(final TestCallBack call) {
return new Thread() {
@Override
public void run() {
File file = new File("/dev/urandom"); // 讀取linux黑洞
try {
FileInputStream in = new FileInputStream(file);
byte[] bytes = new byte[1024];
while (in.read(bytes, 0, 1024) > 0) {
if (Thread.interrupted()) {
throw new InterruptedException("");
}
System.out.println(bytes[0]);
Thread.sleep(100);
long start = System.currentTimeMillis();
call.callback();
System.out.println(call.getName() + " callback finish cost : "
+ (System.currentTimeMillis() - start));
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
}
}
interface TestCallBack {
public void callback() throws Exception;
public String getName();
}

復(fù)制代碼 代碼如下:

package com.agapple.cocurrent;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
public class LockSupportTest {
private static LockSupportTest blocker = new LockSupportTest();
public static void main(String args[]) throws Exception {
lockSupportTest();
parkTest();
interruptParkTest();
interruptSleepTest();
interruptWaitTest();
}
/**
* LockSupport.park對象后,嘗試獲取Thread.blocker對象,調(diào)用其single喚醒
*
* @throws Exception
*/
private static void lockSupportTest() throws Exception {
Thread t = doTest(new TestCallBack() {
@Override
public void callback() throws Exception {
// 嘗試sleep 5s
System.out.println("blocker");
LockSupport.park(blocker);
System.out.println("wakeup now!");
}
@Override
public String getName() {
return "lockSupportTest";
}
});
t.start(); // 啟動讀取線程
Thread.sleep(150);
synchronized (blocker) {
Field field = Thread.class.getDeclaredField("parkBlocker");
field.setAccessible(true);
Object fBlocker = field.get(t);
System.out.println(blocker == fBlocker);
Thread.sleep(100);
System.out.println("notifyAll");
blocker.notifyAll();
}
}
/**
* 嘗試去中斷一個object.wait(),會拋出對應(yīng)的InterruptedException異常
*
* @throws InterruptedException
*/
private static void interruptWaitTest() throws InterruptedException {
final Object obj = new Object();
Thread t = doTest(new TestCallBack() {
@Override
public void callback() throws Exception {
// 嘗試sleep 5s
obj.wait();
System.out.println("wakeup now!");
}
@Override
public String getName() {
return "interruptWaitTest";
}
});
t.start(); // 啟動讀取線程
Thread.sleep(2000);
t.interrupt(); // 檢查下在park時,是否響應(yīng)中斷
}
/**
* 嘗試去中斷一個Thread.sleep(),會拋出對應(yīng)的InterruptedException異常
*
* @throws InterruptedException
*/
private static void interruptSleepTest() throws InterruptedException {
Thread t = doTest(new TestCallBack() {
@Override
public void callback() throws Exception {
// 嘗試sleep 5s
Thread.sleep(5000);
System.out.println("wakeup now!");
}
@Override
public String getName() {
return "interruptSleepTest";
}
});
t.start(); // 啟動讀取線程
Thread.sleep(2000);
t.interrupt(); // 檢查下在park時,是否響應(yīng)中斷
}
/**
* 嘗試去中斷一個LockSupport.park(),會有響應(yīng)但不會拋出InterruptedException異常
*
* @throws InterruptedException
*/
private static void interruptParkTest() throws InterruptedException {
Thread t = doTest(new TestCallBack() {
@Override
public void callback() {
// 嘗試去park 自己線程
LockSupport.parkNanos(blocker, TimeUnit.SECONDS.toNanos(5));
System.out.println("wakeup now!");
}
@Override
public String getName() {
return "interruptParkTest";
}
});
t.start(); // 啟動讀取線程
Thread.sleep(2000);
t.interrupt(); // 檢查下在park時,是否響應(yīng)中斷
}
/**
* 嘗試去中斷一個LockSupport.unPark(),會有響應(yīng)
*
* @throws InterruptedException
*/
private static void parkTest() throws InterruptedException {
Thread t = doTest(new TestCallBack() {
@Override
public void callback() {
// 嘗試去park 自己線程
LockSupport.park(blocker);
System.out.println("wakeup now!");
}
@Override
public String getName() {
return "parkTest";
}
});
t.start(); // 啟動讀取線程
Thread.sleep(2000);
LockSupport.unpark(t);
t.interrupt();
}
public static Thread doTest(final TestCallBack call) {
return new Thread() {
@Override
public void run() {
File file = new File("/dev/urandom"); // 讀取linux黑洞
try {
FileInputStream in = new FileInputStream(file);
byte[] bytes = new byte[1024];
while (in.read(bytes, 0, 1024) > 0) {
if (Thread.interrupted()) {
throw new InterruptedException("");
}
System.out.println(bytes[0]);
Thread.sleep(100);
long start = System.currentTimeMillis();
call.callback();
System.out.println(call.getName() + " callback finish cost : "
+ (System.currentTimeMillis() - start));
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
}
}
interface TestCallBack {
public void callback() throws Exception;
public String getName();
}

最后
發(fā)覺文章越寫越長,那就索性發(fā)到了論壇,大家一起討論下.畢竟文章中描述的都是一些使用層面的東東,并沒有從操作系統(tǒng)或者sun native實現(xiàn)上去介紹Thread的一些機制,熟悉這塊的大牛門也可以出來發(fā)表下高見.
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
国产玖玖精品视频| 韩国19禁主播vip福利视频| 欧美视频在线第一页| 91在线观看下载| 亚洲欧美日韩一区在线| 二区视频在线观看| 78色国产精品| 蜜臀久久99精品久久久久久9| 日韩中文字幕av在线| 亚洲美女偷拍久久| 国产精品边吃奶边做爽| 日韩亚洲欧美中文在线| 亚洲av永久纯肉无码精品动漫| av日韩免费电影| 欧美国产欧美亚州国产日韩mv天天看完整 | 国产精品18久久久久久久久| 国产深夜男女无套内射| 精品免费视频.| 国产精品亚洲欧美在线播放| 精品欧美国产| 色伊人久久综合中文字幕| 免费一级全黄少妇性色生活片| 国产精品久久久久久久久粉嫩av| 成人久久视频在线观看| 佐佐木明希电影| 91成人在线观看国产| 国产日韩v精品一区二区| 亚洲精品国产一区黑色丝袜| 97超碰国产精品女人人人爽| 石原莉奈在线亚洲三区| 日本一欧美一欧美一亚洲视频| 亚洲国产一二三精品无码| 综合婷婷亚洲小说| 91插插插插插插| 麻豆一区区三区四区产品精品蜜桃| 激情成人中文字幕| 国产视频一二三四区| 日本国产在线播放| 不卡av在线播放| 亚洲国产精品99久久久久久久久| 少妇太紧太爽又黄又硬又爽小说| 91文字幕巨乱亚洲香蕉| 欧美精品 日韩| 麻豆传媒一区二区三区| 人妻无码一区二区三区| 精品视频在线观看| 日韩av在线影院| 国产a久久麻豆| 手机毛片在线观看| 一本色道婷婷久久欧美| 中文字幕亚洲一区二区三区| 久久精品夜色噜噜亚洲aⅴ| 国产精品免费av一区二区| 国产黄色一级网站| 成人网欧美在线视频| 精品精品欲导航| 91蝌蚪国产九色| 国产乱码久久久| 在线观看一区二区三区四区| 日产精品久久久一区二区| 久久精品人人爽| 欧美性xxxxx极品少妇| 成人丝袜高跟foot| 亚洲网站免费观看| 欧美午夜激情影院| 九九九在线观看视频| 国产在线观看一区| 国产成人精品国内自产拍免费看| 精品卡一卡二卡三卡四在线| 国产精品白丝在线| 国产成人亚洲精品狼色在线| 国产日韩久久久| 亚欧精品视频一区二区三区| 伊人网在线综合| 9191国产视频| 欧洲亚洲一区| 国产成人免费观看| 国产成人精品日本亚洲专区61| 国产亚洲视频中文字幕视频| 555www色欧美视频| 国产精品久久久久久亚洲伦| 国产高清在线观看免费不卡| 亚州av在线播放| 国产理论视频在线观看| 午夜精品久久久久久久蜜桃| 日本中文字幕网| 欧美精品xxxxx| 91狠狠综合久久久| 911国产在线| 在线观看天堂av| 在线观看美女av| 国产91在线播放九色| 精品国产aaa| 日韩在线一卡二卡| 欧美性生给视频| 老妇女50岁三级| 午夜剧场免费在线观看| 蜜臀av午夜精品久久| 黄色一级视频免费观看| 91麻豆精品成人一区二区| 日韩欧美视频在线免费观看| 国产精彩视频在线| 亚洲日本视频在线观看| 免费黄色片视频| 国产麻豆精品一区| 亚洲 欧美 自拍偷拍| 视频一区二区三区中文字幕| 国产一区二区免费视频| 91丨porny丨国产入口| 国产精品黄色在线观看| 色婷婷精品久久二区二区蜜臀av| 在线综合亚洲欧美在线视频| 日韩国产精品一区| 韩国福利视频一区| 国产日韩一区欧美| 97超碰青青草| 国产99在线 | 亚洲| 日韩电影在线观看一区二区| 五月婷婷六月激情| 中文一区二区在线观看| 欧美日韩电影在线播放| 欧美成人精品一区二区| 亚洲自拍偷拍区| www.射射射| 在线不卡av电影| 91精东传媒理伦片在线观看| 国产一区美女在线| 五月天一区二区三区| 一二美女精品欧洲| 91福利入口| 成人免费无码av| 大地资源高清在线视频观看| japanese国产| 亚洲日本乱码在线观看| 亚洲精品一区二三区不卡| 国产欧美精品日韩精品| 一二三四视频社区在线| 国产99在线 | 亚洲| 手机精品视频在线观看| 欧美日韩亚洲高清| 97人人做人人爱| 黄色一级在线视频| 日本妇女毛茸茸| 国产精品一区免费在线观看| 午夜亚洲福利老司机| 777a∨成人精品桃花网| 日本成熟性欧美| 久久久久久久少妇| 波多野结衣毛片| 亚洲三级电影网站| 国内偷自视频区视频综合| 国产精品久久中文字幕| 亚洲午夜无码久久久久| 亚洲午夜免费视频| 国产乱人伦真实精品视频| 亚洲五月天综合| 午夜精品久久久久久久99老熟妇| 亚洲444eee在线观看| 人人做人人澡人人爽欧美| 日韩精品一区中文字幕| 国产成人三级一区二区在线观看一 | 亚洲二区在线播放| www.黄色网| 国产又粗又猛又爽又黄的网站| 性欧美一区二区| 99久久精品免费精品国产| 亚洲欧美另类中文字幕| 日韩一级特黄毛片| av中文在线观看| 欧美剧在线免费观看网站| 国产在线精品二区| 国产污片在线观看| 精品久久久久久久久久| 久久综合毛片| 亚洲视频在线观看免费视频| 欧美伦理视频网站| 97免费视频观看| 天堂av在线免费| 日韩精品自拍偷拍| 日韩欧美在线一区二区| 东京热一区二区三区四区| 91福利精品第一导航| 日本一区二区三区视频免费看| 精品在线播放视频| 欧美日韩高清一区二区不卡| www.日本在线视频| 国产最新精品精品你懂的| 欧美成人性色生活仑片| 色婷婷av777| 欧美日韩国产中文字幕 | 69av视频在线播放| 中文字幕美女视频| 色菇凉天天综合网| 四虎永久在线精品无码视频| 狠狠色丁香久久婷婷综合丁香| 久久久久久久久久久免费| 日本视频在线免费| 精品视频在线免费看| 一区二区成人网| 亚洲视频在线一区观看| 黄瓜视频免费观看在线观看www| 五月婷婷六月丁香综合| 26uuu日韩精品一区二区| 久久视频精品在线观看| 欧美日韩电影一区| 欧美视频国产视频| 亚洲黄色录像片| 毛片在线视频播放| 亚洲精品第1页| 久久免费视频3| 中文字幕精品综合| 国产免费观看高清视频| 亚洲欧美一区二区视频| 麻豆传媒网站在线观看| 亚洲人成色777777老人头| 日本sm极度另类视频| www.色播.com| 91精品在线影院| 国产在线不卡一区| 亚洲国产日韩美| 亚洲免费大片在线观看| 欧美精品久久久久久久久25p| 色综合久久66| 欧美大波大乳巨大乳| 在线观看91久久久久久| 日韩毛片在线视频| 国产一区二区色| 国产精品99久久久久久似苏梦涵 | 成人无码一区二区三区| 免费久久99精品国产自| 日本一区二区三区免费乱视频| 激情视频综合网| 欧美精品一区二区三区视频 | 中文字幕av观看| 日日噜噜噜夜夜爽亚洲精品| 国产富婆一级全黄大片| 亚洲va韩国va欧美va精四季| 一区二区三区在线观看动漫| 极品人妻一区二区三区| 欧美福利小视频| 国产精品一区不卡| 天天综合网日韩| 中文字幕亚洲天堂| 视频一区欧美日韩| 国语对白做受xxxxx在线中国| 亚洲高清久久久久久| 亚洲免费国产视频| 97干在线视频| 欧美哺乳videos| 手机看片福利在线| 妓院一钑片免看黄大片| 中文欧美在线视频| 国产激情视频一区二区在线观看| 九九热99视频| 久久久亚洲国产| 国产欧美日韩一区二区三区在线观看| 91成人在线观看喷潮蘑菇| 69av视频在线播放| 亚洲高清免费在线| 亚洲一区二区人妻| 不卡影院一区二区| 欧美激情欧美激情在线五月| 国产日韩欧美麻豆| 国产主播在线播放| 裸体大乳女做爰69| 精品国产一区二区三区久久狼黑人| 黄色小说综合网站| 美国黑人一级大黄| 久久亚裔精品欧美| 亚洲精品美女在线观看播放| 国产精品综合在线视频| 亚洲精品视频网址| 亚洲狠狠婷婷综合久久久| 日韩av影院在线观看| 99国产一区二区三精品乱码| 国产无遮挡又黄又爽在线观看 | 精品欧美日韩| 亚洲欧美日韩久久久久久| 91亚洲永久精品| 伦av综合一区| 在线一区二区不卡| 精品视频第一区| 久久久av免费| 色综合天天综合网国产成人综合天 | 国产夫妻性爱视频| 国产精品8888| 国产欧美精品一区二区三区介绍| 欧美一区二区三区思思人| 99久久精品免费看| 精品人妻一区二区三区蜜桃 | 蜜桃91精品入口| 免费不卡欧美自拍视频| 色综合久久88色综合天天| 美女视频网站黄色亚洲| 久久久国产高清| 蜜臀av粉嫩av懂色av| 亚洲高清在线观看一区| 国产成人亚洲综合91| 国产网站欧美日韩免费精品在线观看| 国产精品国产三级国产普通话99| 亚洲精品视频专区| 精品国产乱码一区二区| 美女被到爽高潮视频| 老头吃奶性行交视频| 少妇精品久久久久久久久久| 欧美在线免费看| 在线日韩av观看| 精品国产乱码久久久久久夜甘婷婷| 亚洲六月丁香色婷婷综合久久| 国产一区美女在线| 日韩精品一级中文字幕精品视频免费观看 | 亚洲国产精品无码久久久| www.精品在线| 男人的天堂狠狠干| 日本一区二区高清视频| 成人免费网站在线观看| 97在线免费观看视频| 久久久极品av| 一本色道久久88综合日韩精品| 51精品国自产在线| 欧美网站大全在线观看| 夜夜亚洲天天久久| 国产精品色噜噜| 国产精品网曝门| 国产精品久久看| 亚洲欧美一区二区视频| 欧美激情中文不卡| 国产精品电影一区二区| 欧美激情在线观看视频免费| 久久久久久影视| 中文字幕日韩一区| 亚洲免费观看高清| 午夜精品免费在线| 欧美在线观看视频在线| 欧美日韩一卡二卡| 日韩美女主播在线视频一区二区三区| 欧美日韩五月天| 日韩精品在线观看一区| 久久人人爽人人爽人人片亚洲| 午夜精品久久久久久久白皮肤| 国语对白做受69| 92看片淫黄大片欧美看国产片| 999国内精品视频在线| 色播五月综合| 99久久久精品视频| 天天色天天干天天色| 日本人亚洲人jjzzjjz| 日本丰满少妇做爰爽爽| 日韩国产高清影视| 99精品一区二区三区| 精品国产精品自拍| 亚洲精品自在久久| 欧洲美女7788成人免费视频| 国产精品久久久久免费a∨大胸| 91国产在线免费观看| 国产在线拍揄自揄拍无码| 中文字幕1234区| 欧美爱爱小视频| 视频一区视频二区在线观看| 久久精品网站免费观看| 欧美视频中文一区二区三区在线观看 | 国产精品 日产精品 欧美精品| 亚洲另类在线一区| 亚洲四色影视在线观看| 成人高清视频观看www| 国产在线精品91| 永久免费看片在线播放| 美女视频黄 久久| 亚洲午夜激情网站| 色综合久久88色综合天天看泰| 欧美日韩电影一区二区| 原创真实夫妻啪啪av| 久久国产高清视频| 亚洲天堂一区在线观看| 日韩av一级片| 日本高清免费不卡视频| 日韩免费观看在线观看| 波多野结衣之无限发射| 欧美成人777| 成人动漫中文字幕| 日韩精品中文字幕在线播放| 国产精品视频福利| 亚洲人成人无码网www国产| 在线观看xxx| 欧美高清视频不卡网| 91探花福利精品国产自产在线 | 国产精品久久久免费观看| 亚洲 欧美 自拍偷拍| 欧美在线观看视频一区二区| 国产在线久久久| 99热这里只有精品2| 亚洲av成人无码久久精品老人 | 91网址在线看| 亚洲视频在线观看| 女人色极品影院| 国产女人18毛片水真多| 色噜噜久久综合| 久久久久久草| 亚洲 欧美 视频| 午夜视频一区二区三区| 成人乱色短篇合集| 欧美一区二区三区观看| 亚洲天堂成人网| 亚洲aⅴ日韩av电影在线观看| 女人黄色一级片| 亚洲国产wwwccc36天堂| 欧洲亚洲一区| 懂色av一区二区三区四区| 中文字幕欧美日韩va免费视频| 一级做a免费视频|