Lock:java多线程编程核心技术读书笔记
1.ReentrantLock
1.1实现同步:测试一
public class MyService {
private Lock lock = new ReentrantLock();
public void testMethod() {
lock.lock();
for (int i = 0; i < 5; i++) {
System.out.println("ThreadName=" + Thread.currentThread().getName()
+ (" " + (i + 1)));
}
lock.unlock();
}
}
public class MyThread extends Thread {
private MyService service;
public MyThread(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class Run {
public static void main(String[] args) {
MyService service = new MyService();
MyThread a1 = new MyThread(service);
MyThread a2 = new MyThread(service);
MyThread a3 = new MyThread(service);
MyThread a4 = new MyThread(service);
MyThread a5 = new MyThread(service);
a1.start();
a2.start();
a3.start();
a4.start();
a5.start();
}
}
运行结果:
ThreadName=Thread-0 1
ThreadName=Thread-0 2
ThreadName=Thread-0 3
ThreadName=Thread-0 4
ThreadName=Thread-0 5//一个线程执行完成才会执行另一个线程
ThreadName=Thread-4 1
ThreadName=Thread-4 2
ThreadName=Thread-4 3
ThreadName=Thread-4 4
ThreadName=Thread-4 5
ThreadName=Thread-3 1
ThreadName=Thread-3 2
ThreadName=Thread-3 3
ThreadName=Thread-3 4
ThreadName=Thread-3 5
ThreadName=Thread-2 1
ThreadName=Thread-2 2
ThreadName=Thread-2 3
ThreadName=Thread-2 4
ThreadName=Thread-2 5
ThreadName=Thread-1 1
ThreadName=Thread-1 2
ThreadName=Thread-1 3
ThreadName=Thread-1 4
ThreadName=Thread-1 5
1.2实现同步:测试二
public class MyService {
private Lock lock = new ReentrantLock();
public void methodA() {
try {
lock.lock();
System.out.println("methodA begin ThreadName="
+ Thread.currentThread().getName() + " time="
+ System.currentTimeMillis());
Thread.sleep(5000);
System.out.println("methodA end ThreadName="
+ Thread.currentThread().getName() + " time="
+ System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void methodB() {
try {
lock.lock();
System.out.println("methodB begin ThreadName="
+ Thread.currentThread().getName() + " time="
+ System.currentTimeMillis());
Thread.sleep(5000);
System.out.println("methodB end ThreadName="
+ Thread.currentThread().getName() + " time="
+ System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class ThreadA extends Thread {
private MyService service;
public ThreadA(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.methodA();
}
}
public class ThreadAA extends Thread {
private MyService service;
public ThreadAA(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.methodA();
}
}
public class ThreadB extends Thread {
private MyService service;
public ThreadB(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.methodB();
}
}
public class ThreadBB extends Thread {
private MyService service;
public ThreadBB(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.methodB();
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadAA aa = new ThreadAA(service);
aa.setName("AA");
aa.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
ThreadBB bb = new ThreadBB(service);
bb.setName("BB");
bb.start();
}
}
运行结果:
methodA begin ThreadName=A time=1472804595450
methodA end ThreadName=A time=1472804600451
methodA begin ThreadName=AA time=1472804600451
methodA end ThreadName=AA time=1472804605451
methodB begin ThreadName=B time=1472804605451
methodB end ThreadName=B time=1472804610452
methodB begin ThreadName=BB time=1472804610452
methodB end ThreadName=BB time=1472804615452
1.3使用Condition现实等待/通知:
注意:在condition.await()之前需要调用lock.lock()方法获取同步监视器
public class MyService {
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void waitMethod() {
try {
lock.lock();
System.out.println("A");
condition.await();
System.out.println("B");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
System.out.println("锁释放了!");
}
}
}
public class MyThreadA extends Thread {
private MyService myService;
public MyThreadA(MyService myService) {
super();
this.myService = myService;
}
@Override
public void run() {
myService.waitMethod();
}
}
public class Run {
public static void main(String[] args) {
MyService myService = new MyService();
MyThreadA a = new MyThreadA(myService);
a.start();
}
}
运行结果:只打印A,因为打印A以后await程序进入waiting状态了
A
public class MyService {
private Lock lock = new ReentrantLock();
public Condition condition = lock.newCondition();
public void await() {
try {
lock.lock();
System.out.println(" await时间为" + System.currentTimeMillis());
condition.await();
System.out.println("code after await");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("await unlock");
lock.unlock();
}
}
public void signal() {
try {
lock.lock();
System.out.println("signal时间为" + System.currentTimeMillis());
condition.signal();
System.out.println("after signal");
} finally {
System.out.println("signal unlock");
lock.unlock();
}
}
}
public class ThreadA extends Thread {
private MyService service;
public ThreadA(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.await();
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
ThreadA a = new ThreadA(service);
a.start();
Thread.sleep(3000);
service.signal();
}
}
运行结果:
await时间为1472805741561
signal时间为1472805744561
after signal
signal unlock
code after await
await unlock
1.4使用condition通知部分线程
public class MyService {
private Lock lock = new ReentrantLock();
public Condition conditionA = lock.newCondition();
public Condition conditionB = lock.newCondition();
public void awaitA() {
try {
lock.lock();
System.out.println("begin awaitA时间为" + System.currentTimeMillis()
+ " ThreadName=" + Thread.currentThread().getName());
conditionA.await();
System.out.println(" end awaitA时间为" + System.currentTimeMillis()
+ " ThreadName=" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void awaitB() {
try {
lock.lock();
System.out.println("begin awaitB时间为" + System.currentTimeMillis()
+ " ThreadName=" + Thread.currentThread().getName());
conditionB.await();
System.out.println(" end awaitB时间为" + System.currentTimeMillis()
+ " ThreadName=" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void signalAll_A() {
try {
lock.lock();
System.out.println(" signalAll_A时间为" + System.currentTimeMillis()
+ " ThreadName=" + Thread.currentThread().getName());
conditionA.signalAll();
} finally {
lock.unlock();
}
}
public void signalAll_B() {
try {
lock.lock();
System.out.println(" signalAll_B时间为" + System.currentTimeMillis()
+ " ThreadName=" + Thread.currentThread().getName());
conditionB.signalAll();
} finally {
lock.unlock();
}
}
}
public class ThreadA extends Thread {
private MyService service;
public ThreadA(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.awaitA();
}
}
public class ThreadB extends Thread {
private MyService service;
public ThreadB(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.awaitB();
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
Thread.sleep(3000);
service.signalAll_A();//通知A
service.signalAll_B();//通知B
}
}
1.5生产者消费者模式:一对一交替打印
public class MyService {
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private boolean hasValue = false;
public void set() {
try {
lock.lock();
while (hasValue == true) {
condition.await();
}
System.out.println("打印★");
hasValue = true;
condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void get() {
try {
lock.lock();
while (hasValue == false) {
condition.await();
}
System.out.println("打印☆");
hasValue = false;
condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class MyThreadA extends Thread {
private MyService myService;
public MyThreadA(MyService myService) {
super();
this.myService = myService;
}
@Override
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
myService.set();
}
}
}
public class MyThreadB extends Thread {
private MyService myService;
public MyThreadB(MyService myService) {
super();
this.myService = myService;
}
@Override
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
myService.get();
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
MyService myService = new MyService();
MyThreadA a = new MyThreadA(myService);
a.start();
MyThreadB b = new MyThreadB(myService);
b.start();
}
}
1.6生产者消费者模式:多对多打印
public class MyService {
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private boolean hasValue = false;
public void set() {
try {
lock.lock();
while (hasValue == true) {
System.out.println("有可能★★连续");
condition.await();
}
System.out.println("打印★");
hasValue = true;
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void get() {
try {
lock.lock();
while (hasValue == false) {
System.out.println("有可能☆☆连续");
condition.await();
}
System.out.println("打印☆");
hasValue = false;
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class MyThreadA extends Thread {
private MyService myService;
public MyThreadA(MyService myService) {
super();
this.myService = myService;
}
@Override
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
myService.set();
}
}
}
public class MyThreadB extends Thread {
private MyService myService;
public MyThreadB(MyService myService) {
super();
this.myService = myService;
}
@Override
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
myService.get();
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
MyThreadA[] threadA = new MyThreadA[10];
MyThreadB[] threadB = new MyThreadB[10];
for (int i = 0; i < 10; i++) {
threadA[i] = new MyThreadA(service);
threadB[i] = new MyThreadB(service);
threadA[i].start();
threadB[i].start();
}
}
}
1.7公平锁与非公平锁
Lock分为公平锁和不公平锁
公平锁:线程获取锁的顺序是按照线程枷锁的顺序来的
不公平锁:锁的抢占机制,随机获取锁
public class Service {
private ReentrantLock lock;
public Service(boolean isFair) {
super();
lock = new ReentrantLock(isFair);
}
public void serviceMethod() {
try {
lock.lock();
System.out.println("ThreadName=" + Thread.currentThread().getName()
+ "获得锁定");
} finally {
lock.unlock();
}
}
}
public class RunFair {
public static void main(String[] args) throws InterruptedException {
final Service service = new Service(true);
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("★线程" + Thread.currentThread().getName()
+ "运行了");
service.serviceMethod();
}
};
Thread[] threadArray = new Thread[10];
for (int i = 0; i < 10; i++) {
threadArray[i] = new Thread(runnable);
}
for (int i = 0; i < 10; i++) {
threadArray[i].start();
}
}
}
public class RunNotFair {
public static void main(String[] args) throws InterruptedException {
final Service service = new Service(false);
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("★线程" + Thread.currentThread().getName()
+ "运行了");
service.serviceMethod();
}
};
Thread[] threadArray = new Thread[10];
for (int i = 0; i < 10; i++) {
threadArray[i] = new Thread(runnable);
}
for (int i = 0; i < 10; i++) {
threadArray[i].start();
}
}
}
1.8getHoldCount(),getQueueLength(),getWaitQueueLength();方法测试
1.8.1getHoldCount查询当前线程保持此锁定的个数,也就是调用lock的次数
public class Service {
private ReentrantLock lock = new ReentrantLock();
public void serviceMethod1() {
try {
lock.lock();
System.out.println("serviceMethod1 getHoldCount="
+ lock.getHoldCount());
Thread.sleep(3000);
// System.out.println("before call method2");
// serviceMethod2();
// System.out.println("after call method2");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
System.out.println("before method1 release lock");
lock.unlock();
System.out.println("after method1 release lock");
}
}
public void serviceMethod2() {
try {
lock.lock();
System.out.println("serviceMethod2 getHoldCount="
+ lock.getHoldCount());
} finally {
lock.unlock();
}
}
}
public class Run {
public static void main(String[] args) {
Service service = new Service();
service.serviceMethod1();
System.out.println("before call method2");
service.serviceMethod2();
System.out.println("after call method2");
}
}
运行结果:分开调用method1和method2的时候的效果,同步
serviceMethod1 getHoldCount=1
before method1 release lock
after method1 release lock
before call method2
serviceMethod2 getHoldCount=1
after call method2
嵌套调用等于是嵌套上锁,不会等待method1执行完成之后再去执行method2,而是调用就直接执行
public class Service {
private ReentrantLock lock = new ReentrantLock();
public void serviceMethod1() {
try {
lock.lock();
System.out.println("serviceMethod1 getHoldCount="
+ lock.getHoldCount());
System.out.println("before call method2");
serviceMethod2();
System.out.println("after call method2");
} finally {
System.out.println("before method1 release lock");
lock.unlock();
System.out.println("after method1 release lock");
}
}
public void serviceMethod2() {
try {
lock.lock();
System.out.println("serviceMethod2 getHoldCount="
+ lock.getHoldCount());
} finally {
lock.unlock();
}
}
}
public class Run {
public static void main(String[] args) {
Service service = new Service();
service.serviceMethod1();
}
}
运行结果:
serviceMethod1 getHoldCount=1
before call method2
serviceMethod2 getHoldCount=2
after call method2
before method1 release lock
after method1 release lock
1.8.2getQueueLength返回正在等待获取此锁定的个数
public class Service {
public ReentrantLock lock = new ReentrantLock();
public void serviceMethod1() {
try {
lock.lock();
System.out.println("ThreadName=" + Thread.currentThread().getName()
+ "进入方法!");
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
final Service service = new Service();
Runnable runnable = new Runnable() {
@Override
public void run() {
service.serviceMethod1();
}
};
Thread[] threadArray = new Thread[10];
for (int i = 0; i < 10; i++) {
threadArray[i] = new Thread(runnable);
}
for (int i = 0; i < 10; i++) {
threadArray[i].start();
}
Thread.sleep(2000);
System.out.println("有线程数:" + service.lock.getQueueLength() + "在等待获取锁!");
}
}
运行结果:
ThreadName=Thread-0进入方法!
有线程数:9在等待获取锁!
1.8.3getWaitQueueLength
假如有5个线程,每个线程都执行了condition.await,则调用该方法返回5
public class Service {
private ReentrantLock lock = new ReentrantLock();
private Condition newCondition = lock.newCondition();
public void waitMethod() {
try {
lock.lock();
newCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void notityMethod() {
try {
lock.lock();
System.out.println("有" + lock.getWaitQueueLength(newCondition)
+ "个线程正在等待newCondition");
newCondition.signal();
System.out.println("有" + lock.getWaitQueueLength(newCondition)
+ "个线程正在等待newCondition");
newCondition.signalAll();
System.out.println("有" + lock.getWaitQueueLength(newCondition)
+ "个线程正在等待newCondition");
} finally {
lock.unlock();
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
final Service service = new Service();
Runnable runnable = new Runnable() {
@Override
public void run() {
service.waitMethod();
}
};
Thread[] threadArray = new Thread[10];
for (int i = 0; i < 10; i++) {
threadArray[i] = new Thread(runnable);
}
for (int i = 0; i < 10; i++) {
threadArray[i].start();
}
Thread.sleep(2000);
service.notityMethod();
}
}
1.9 hasQueuedThread(),hasQueuedThreads(),hasWaiters()
1.9.1 hasQueuedThread hasQueuedThreads
hasQueuedThreads查询是否有线程在等待获取锁
hasQueuedThread(thread)查询指定线程是否在等待获取锁
public class Service {
public ReentrantLock lock = new ReentrantLock();
public Condition newCondition = lock.newCondition();
public void waitMethod() {
try {
lock.lock();
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
System.out.println(Thread.currentThread().getName()+" unlock ");
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
final Service service = new Service();
Runnable runnable = new Runnable() {
@Override
public void run() {
service.waitMethod();
}
};
Thread threadA = new Thread(runnable);
threadA.start();
Thread.sleep(500);
Thread threadB = new Thread(runnable);
threadB.start();
Thread.sleep(500);
System.out.println(service.lock.hasQueuedThread(threadA));
System.out.println(service.lock.hasQueuedThread(threadB));
System.out.println(service.lock.hasQueuedThreads());
}
}
运行结果:
false:threadA正在等待获取锁?false,threadA已经获取锁
true:threadB正在等待获取锁
true:有线程在等待获取锁
1.9.2 hasWaiters(condition)
是否有线程在等待与此锁定相关的condition条件
public class Service {
private ReentrantLock lock = new ReentrantLock();
private Condition newCondition = lock.newCondition();
public void waitMethod() {
try {
lock.lock();
newCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void notityMethod() {
try {
lock.lock();
System.out.println("有没有线程正在等待newCondition?"
+ lock.hasWaiters(newCondition) + " 线程数是多少?"
+ lock.getWaitQueueLength(newCondition));
newCondition.signal();
System.out.println("有没有线程正在等待newCondition?"
+ lock.hasWaiters(newCondition) + " 线程数是多少?"
+ lock.getWaitQueueLength(newCondition));
newCondition.signalAll();
System.out.println("有没有线程正在等待newCondition?"
+ lock.hasWaiters(newCondition) + " 线程数是多少?"
+ lock.getWaitQueueLength(newCondition));
} finally {
lock.unlock();
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
final Service service = new Service();
Runnable runnable = new Runnable() {
@Override
public void run() {
service.waitMethod();
}
};
Thread[] threadArray = new Thread[10];
for (int i = 0; i < 10; i++) {
threadArray[i] = new Thread(runnable);
}
for (int i = 0; i < 10; i++) {
threadArray[i].start();
}
Thread.sleep(2000);
service.notityMethod();
}
}
运行结果:
有没有线程正在等待newCondition?true 线程数是多少?10
有没有线程正在等待newCondition?true 线程数是多少?9
有没有线程正在等待newCondition?false 线程数是多少?0
1.10 isFair(),isHeldByCurrentThread(),isLocked()
1.10.1 isFair判断是否是公平锁
public class Service {
private ReentrantLock lock;
public Service(boolean isFair) {
super();
lock = new ReentrantLock(isFair);
}
public void serviceMethod() {
try {
lock.lock();
System.out.println("公平锁情况:" + lock.isFair());
} finally {
lock.unlock();
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
final Service service1 = new Service(true);
Runnable runnable = new Runnable() {
@Override
public void run() {
service1.serviceMethod();
}
};
Thread thread = new Thread(runnable);
thread.start();
final Service service2 = new Service(false);
runnable = new Runnable() {
@Override
public void run() {
service2.serviceMethod();
}
};
thread = new Thread(runnable);
thread.start();
}
}
运行结果:
公平锁情况:true
公平锁情况:false
1.10.2 isHeldByCurrentThread查询当前线程是否保持此锁定
public class Service {
private ReentrantLock lock;
public Service(boolean isFair) {
super();
lock = new ReentrantLock(isFair);
}
public void serviceMethod() {
try {
System.out.println(lock.isHeldByCurrentThread());
lock.lock();
System.out.println(lock.isHeldByCurrentThread());
} finally {
lock.unlock();
System.out.println(lock.isHeldByCurrentThread());
}
}
}
public class Run {
public static void main(String args[]){
final Service service = new Service(true);
Runnable runable = new Runnable() {
@Override
public void run() {
service.serviceMethod();
}
};
Thread thread = new Thread(runable);
thread.start();
}
}
1.10.3 isLocked查询此锁定是否被某个线程锁保持
public class Service {
private ReentrantLock lock;
public Service(boolean isFair) {
super();
lock = new ReentrantLock(isFair);
}
public void serviceMethod() {
try {
System.out.println(lock.isLocked());
lock.lock();
System.out.println(lock.isLocked());
} finally {
lock.unlock();
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
final Service service1 = new Service(true);
Runnable runnable = new Runnable() {
@Override
public void run() {
service1.serviceMethod();
}
};
Thread thread = new Thread(runnable);
thread.start();
}
}
1.11 lockInterruptibly(),tryLock(),tryLock(timeout,unit);
1.11.1lockInterruptibly()
如果当前未被中断,则获取锁定,如果已经被中断,则抛出异常
public class MyService {
public ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void waitMethod() {
try {
lock.lock();
System.out
.println("lock begin " + Thread.currentThread().getName());
for (int i = 0; i < Integer.MAX_VALUE / 10; i++) {
String newString = new String();
Math.random();
}
System.out
.println("lock end " + Thread.currentThread().getName());
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
final MyService service = new MyService();
Runnable runnableRef = new Runnable() {
@Override
public void run() {
service.waitMethod();
}
};
Thread threadA = new Thread(runnableRef);
threadA.setName("A");
threadA.start();
Thread.sleep(500);
Thread threadB = new Thread(runnableRef);
threadB.setName("B");
threadB.start();
threadB.interrupt();// 打标记
System.out.println("main end!");
}
}
public class MyService {
public ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void waitMethod() {
try {
lock.lockInterruptibly();
System.out.println("lock " + Thread.currentThread().getName());
for (int i = 0; i < Integer.MAX_VALUE / 10; i++) {
String newString = new String();
Math.random();
}
} catch (InterruptedException e) {
System.out.println("线程"+Thread.currentThread().getName()+"进入catch~!");
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
final MyService service = new MyService();
Runnable runnableRef = new Runnable() {
@Override
public void run() {
service.waitMethod();
}
};
Thread threadA = new Thread(runnableRef);
threadA.setName("A");
threadA.start();
Thread.sleep(500);
Thread threadB = new Thread(runnableRef);
threadB.setName("B");
threadB.start();
threadB.interrupt();
}
}
1.11.2tryLock()
仅在调用锁定未被另一个线程保持的情况下,才获取该锁定
public class MyService {
public ReentrantLock lock = new ReentrantLock();
public void waitMethod() {
if (lock.tryLock()) {
System.out.println(Thread.currentThread().getName() + "获得锁");
} else {
System.out.println(Thread.currentThread().getName() + "没有获得锁");
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
final MyService service = new MyService();
Runnable runnableRef = new Runnable() {
@Override
public void run() {
service.waitMethod();
}
};
Thread threadA = new Thread(runnableRef);
threadA.setName("A");
threadA.start();
Thread threadB = new Thread(runnableRef);
threadB.setName("B");
threadB.start();
}
}
运行结果:
B没有获得锁
A获得锁
1.11.3tryLock(timeout,unit)
如果锁定在给定时间内没有被另一个线程保持,且当前线程没有被中断,则获取该锁定
public class MyService {
public ReentrantLock lock = new ReentrantLock();
public void waitMethod() {
try {
if (lock.tryLock(3, TimeUnit.SECONDS)) {
System.out.println(" " + Thread.currentThread().getName()
+ "获得锁的时间:" + System.currentTimeMillis());
Thread.sleep(10000);
} else {
System.out.println(" " + Thread.currentThread().getName()
+ "没有获得锁");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
final MyService service = new MyService();
Runnable runnableRef = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()
+ "调用waitMethod时间:" + System.currentTimeMillis());
service.waitMethod();
}
};
Thread threadA = new Thread(runnableRef);
threadA.setName("A");
threadA.start();
Thread threadB = new Thread(runnableRef);
threadB.setName("B");
threadB.start();
}
}
1.14 awaitUninterruptibly()
public class Service {
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void testMethod() {
try {
lock.lock();
System.out.println("wait begin");
condition.awaitUninterruptibly();
System.out.println("wait end");
} finally {
lock.unlock();
}
}
}
public class MyThread extends Thread {
private Service service;
public MyThread(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class Run {
public static void main(String[] args) {
try {
Service service = new Service();
MyThread myThread = new MyThread(service);
myThread.start();
Thread.sleep(3000);
myThread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Service {
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void testMethod() {
try {
lock.lock();
System.out.println("wait begin");
condition.await();
System.out.println("wait end");
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("catch");
} finally {
lock.unlock();
}
}
}
public class MyThread extends Thread {
private Service service;
public MyThread(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class Run {
public static void main(String[] args) {
try {
Service service = new Service();
MyThread myThread = new MyThread(service);
myThread.start();
Thread.sleep(3000);
myThread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
1.15waitUtil
在等待时间到达之前可以被唤醒
public class Service {
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void waitMethod() {
try {
Calendar calendarRef = Calendar.getInstance();
calendarRef.add(Calendar.SECOND, 10);
lock.lock();
System.out
.println("wait begin timer=" + System.currentTimeMillis());
condition.awaitUntil(calendarRef.getTime());
System.out
.println("wait end timer=" + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void notifyMethod() {
try {
Calendar calendarRef = Calendar.getInstance();
calendarRef.add(Calendar.SECOND, 10);
lock.lock();
System.out
.println("notify begin timer=" + System.currentTimeMillis());
condition.signalAll();
System.out
.println("notify end timer=" + System.currentTimeMillis());
} finally {
lock.unlock();
}
}
}
public class MyThreadA extends Thread {
private Service service;
public MyThreadA(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.waitMethod();
}
}
public class MyThreadB extends Thread {
private Service service;
public MyThreadB(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.notifyMethod();
}
}
public class Run1 {
public static void main(String[] args) throws InterruptedException {
Service service = new Service();
MyThreadA myThreadA = new MyThreadA(service);
myThreadA.start();
}
}
public class Run2 {
public static void main(String[] args) throws InterruptedException {
Service service = new Service();
MyThreadA myThreadA = new MyThreadA(service);
myThreadA.start();
Thread.sleep(2000);
MyThreadB myThreadB = new MyThreadB(service);
myThreadB.start();
}
}
1.16使用Condition实现顺序执行
public class F {
volatile public static int nextPrintWho = 1;
}
public class Run {
volatile private static int nextPrintWho = 1;
private static ReentrantLock lock = new ReentrantLock();
final private static Condition conditionA = lock.newCondition();
final private static Condition conditionB = lock.newCondition();
final private static Condition conditionC = lock.newCondition();
public static void main(String[] args) {
Thread threadA = new Thread() {
public void run() {
try {
lock.lock();
while (nextPrintWho != 1) {
conditionA.await();
}
for (int i = 0; i < 3; i++) {
System.out.println("ThreadA " + (i + 1));
}
nextPrintWho = 2;
conditionB.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
Thread threadB = new Thread() {
public void run() {
try {
lock.lock();
while (nextPrintWho != 2) {
conditionB.await();
}
for (int i = 0; i < 3; i++) {
System.out.println("ThreadB " + (i + 1));
}
nextPrintWho = 3;
conditionC.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
Thread threadC = new Thread() {
public void run() {
try {
lock.lock();
while (nextPrintWho != 3) {
conditionC.await();
}
for (int i = 0; i < 3; i++) {
System.out.println("ThreadC " + (i + 1));
}
nextPrintWho = 1;
conditionA.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
Thread[] aArray = new Thread[5];
Thread[] bArray = new Thread[5];
Thread[] cArray = new Thread[5];
for (int i = 0; i < 5; i++) {
aArray[i] = new Thread(threadA);
bArray[i] = new Thread(threadB);
cArray[i] = new Thread(threadC);
aArray[i].start();
bArray[i].start();
cArray[i].start();
}
}
}
2.ReentrantReadWriteLock
使用ReentrantReadWriteLock可以同时进行读操作,但是同一时刻只允许一个Thread进行写操作
2.1读读共享
public class Service {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void read() {
try {
try {
lock.readLock().lock();
System.out.println("获得读锁" + Thread.currentThread().getName()
+ " " + System.currentTimeMillis());
Thread.sleep(10000);
} finally {
lock.readLock().unlock();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.read();
}
}
public class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.read();
}
}
public class Run {
public static void main(String[] args) {
Service service = new Service();
ThreadA a = new ThreadA(service);
a.setName("A");
ThreadB b = new ThreadB(service);
b.setName("B");
a.start();
b.start();
}
}
2.2写写互斥
public class Service {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void write() {
try {
try {
lock.writeLock().lock();
System.out.println("获得写锁" + Thread.currentThread().getName()
+ " " + System.currentTimeMillis());
Thread.sleep(10000);
System.out.println(Thread.currentThread().getName()+" 10s end");
} finally {
lock.writeLock().unlock();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.write();
}
}
public class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.write();
}
}
public class Run {
public static void main(String[] args) {
Service service = new Service();
ThreadA a = new ThreadA(service);
a.setName("A");
ThreadB b = new ThreadB(service);
b.setName("B");
a.start();
b.start();
}
}
运行结果:
获得写锁A 1472949363124
A 10s end
获得写锁B 1472949373139
B 10s end
2.3读写互斥
public class Service {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void read() {
try {
try {
lock.readLock().lock();
System.out.println("获得读锁" + Thread.currentThread().getName()
+ " " + System.currentTimeMillis());
Thread.sleep(10000);
System.out.println("read method end");
} finally {
lock.readLock().unlock();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void write() {
try {
try {
lock.writeLock().lock();
System.out.println("获得写锁" + Thread.currentThread().getName()
+ " " + System.currentTimeMillis());
Thread.sleep(10000);
System.out.println("write method end");
} finally {
lock.writeLock().unlock();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.read();
}
}
public class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.write();
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
Service service = new Service();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
Thread.sleep(1000);
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
}
}
运行结果:
获得读锁A 1472949545776
read method end
获得写锁B 1472949555791
write method end
2.4写读互斥
public class Service {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void read() {
try {
try {
lock.readLock().lock();
System.out.println("获得读锁" + Thread.currentThread().getName()
+ " " + System.currentTimeMillis());
Thread.sleep(10000);
} finally {
lock.readLock().unlock();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void write() {
try {
try {
lock.writeLock().lock();
System.out.println("获得写锁" + Thread.currentThread().getName()
+ " " + System.currentTimeMillis());
Thread.sleep(10000);
} finally {
lock.writeLock().unlock();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.read();
}
}
public class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
super();
this.service = service;
}
@Override
public void run() {
service.write();
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
Service service = new Service();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
Thread.sleep(1000);
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
}
}
运行结果:
获得写锁B 1472949691959
获得读锁A 1472949701959
网友评论