1、例子代码,可以先忽略ReadWriteLock相关代码,重点看ExecutorService 就行。
public class ReadWriteLockTest {
//private static Lock lock = new ReentrantLock();
private static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private static Lock readLock = readWriteLock.readLock();
private static Lock writeLock = readWriteLock.writeLock();
private static int number = 0;
public void read(Lock lock) {
lock.lock();
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("读线程" + Thread.currentThread() + "--" + number);
lock.unlock();
throw new RuntimeException();
}
public void write(Lock lock, int value) {
lock.lock();
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
number = value;
System.out.println("写线程" + Thread.currentThread() + "--" + number);
lock.unlock();
}
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(50);
// executor.execute(new Runnable() {
//
// public void run() {
// new ReadWriteLockTest().read(readLock);
// //new ReadWriteLockTest().read(lock);
// }
// });
//
// Future future = executor.submit(new Runnable() {
//
// public void run() {
// new ReadWriteLockTest().read(readLock);
// //new ReadWriteLockTest().read(lock);
// }
// });
// try {
// future.get();
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (ExecutionException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
for (int i = 0; i < 20; i++) {
executor.submit(new Runnable() {
public void run() {
new ReadWriteLockTest().read(readLock);
// new ReadWriteLockTest().read(lock);
}
});
executor.submit(new Runnable() {
public void run() {
new ReadWriteLockTest().write(writeLock, new Random().nextInt());
// new ReadWriteLockTest().write(lock, new Random().nextInt());
}
});
}
// for (int i = 0; i < 20; i++) {
// new Thread(new Runnable() {
//
// public void run() {
// new ReadWriteLockTest().write(writeLock, new Random().nextInt());
// //new ReadWriteLockTest().write(lock, new Random().nextInt());
// }
// }).start();
// }
// for (int i = 0; i < 20; i++) {
// new Thread(new Runnable() {
//
// public void run() {
// new ReadWriteLockTest().read(readLock);
// // new ReadWriteLockTest().read(lock);
// }
// }).start();
// }
}
}
ExecutorService.execute方法代码如下:
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
如果提交的任务不需要一个结果的话直接用execute()会提升很多性能。
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
包装成FutureTask,当执行到run方法时,我们为何没有看到有Exception抛出来?真相在此,一个try–catch吞噬了所有异常:
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
runner = null;
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
最后只有在get方法中才可以抛出异常,所以,使用submit时的注意了,执行时并没有抛出异常中断父线程的执行,而你还需要get一下才行,否则这问题很难找。
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
s = awaitDone(false, 0L);
return report(s);
}
public V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
if (unit == null)
throw new NullPointerException();
int s = state;
if (s <= COMPLETING &&
(s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
throw new TimeoutException();
return report(s);
}
结论请自己脑补,区别都列出来了。