ReentrantLock的基础了解
package cn.limbo.thread.ReentrantLockTest;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by lhh on 2017/12/15.
*/
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();
}
}
class MyThread extends Thread {
private MyService myService;
public MyThread (MyService myService) {
super ();
this .myService = myService;
}
@Override
public void run () {
myService.testMethod();
}
}
class Run {
public static void main (String[] args) {
MyService myService = new MyService();
MyThread a1 = new MyThread(myService);
MyThread a2 = new MyThread(myService);
MyThread a3 = new MyThread(myService);
MyThread a4 = new MyThread(myService);
MyThread a5 = new MyThread(myService);
a1.start();
a2.start();
a3.start();
a5.start();
a4.start();
}
}
实现正确使用Condition实现等待通知
package cn.limbo.thread.MustUseMoreCondition_OK;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyService {
private Lock lock = new ReentrantLock();
private Condition conditionA = lock .newCondition();
private 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();
}
}
}
class ThreadA extends Thread{
private MyService service;
public ThreadA (MyService service) {
super();
this .service = service;
}
@Override
public void run () {
service.awaitA();
}
}
class ThreadB extends Thread{
private MyService service;
public ThreadB (MyService service) {
super();
this .service = service;
}
@Override
public void run () {
service.awaitB();
}
}
class Run{
public static void main (String[] args) throws InterruptedException {
MyService myService = new MyService();
ThreadA threadA = new ThreadA(myService);
threadA.setName("A" );
threadA.start();
ThreadB threadB = new ThreadB(myService);
threadB.setName("B" );
threadB.start();
Thread.sleep(3000 );
System.out .println("*************" );
myService.signalAll_A();
}
}
打印输出
begin awaitA 时间为 1513336178272 ThreadName =A
begin awaitB 时间为 1513336178274 ThreadName = B
*************
signalAll_A 的时间为1513336181278 ThreadName = main
end awaitA 时间为 1513336181279 ThreadName =A
说明
使用ReentrantLock对象可以唤醒制定种类的线程,这是控制部分线程的方便行为