一:使用Lock实现多线程同步
? 在jdk并发包中,可以使用ReentrantLock类来实现线程之间的同步,Lock.lock()和lock.unLock()实现加锁和释放锁,其一般用于try?catch?finally中。
public class MyService {
private Lock lock = new ReentrantLock();
public void testMethod(){
lock.lock();
for(int i=0;i<5;i++){
System.out.println("当前线程:" + Thread.currentThread().getName() + "运行了testMethod方法,值:" + (i+1));
}
lock.unlock();
}
public void testMethod2(){
lock.lock();
for(int i=0;i<5;i++){
System.out.println("当前线程:" + Thread.currentThread().getName() + "运行了testMethod2方法,值:" + (i+1));
}
lock.unlock();
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
MyService myService = new MyService();
ThreadA threadA = new ThreadA(myService);
ThreadB threadB = new ThreadB(myService);
threadA.start();
threadB.start();
}
}
?
public class ThreadA extends Thread {
private MyService myService;
public ThreadA(MyService myService) {
this.myService = myService;
}
@Override
public void run() {
super.run();
myService.testMethod();
}
}
?
public class ThreadB extends Thread {
private MyService myService;
public ThreadB(MyService myService) {
this.myService = myService;
}
@Override
public void run() {
super.run();
myService.testMethod2();
}
}
?
打印结果: 当前线程:Thread-0运行了testMethod方法,值:1 当前线程:Thread-0运行了testMethod方法,值:2 当前线程:Thread-0运行了testMethod方法,值:3 当前线程:Thread-0运行了testMethod方法,值:4 当前线程:Thread-0运行了testMethod方法,值:5 当前线程:Thread-1运行了testMethod2方法,值:1 当前线程:Thread-1运行了testMethod2方法,值:2 当前线程:Thread-1运行了testMethod2方法,值:3 当前线程:Thread-1运行了testMethod2方法,值:4 当前线程:Thread-1运行了testMethod2方法,值:5
二:使用Condition实现等待通知
? 传统的Wait和Notify也可以实现线程之间的通信,但是如果我们有个这样的需求,多线程在唤醒的时候,我们想唤醒指定的某一个线程,而不是随机唤醒一个,这个时候我们就可以使用Condition来实现了。
public class MyService {
private Lock lock = new ReentrantLock();
public Condition conditionA = lock.newCondition();
public Condition conditionB = lock.newCondition();
public void methodA() {
lock.lock();
System.out.println("begin methodA : "
+ Thread.currentThread().getName());
try {
conditionA.await();
System.out.println("end methodA : "
+ Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
?
public void methodB() {
lock.lock();
System.out.println("begin methodB : "
+ Thread.currentThread().getName());
try {
conditionB.await();
System.out.println("end methodB : "
+ Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
?
public void singalAll_A(){
lock.lock();
System.out.println("singalAll_A:" + Thread.currentThread().getName());
conditionA.signalAll();
lock.unlock();
}
public void singalAll_B(){
lock.lock();
System.out.println("singalAll_B:" + Thread.currentThread().getName());
conditionB.signalAll();
lock.unlock();
}
}
?
public class Run {
public static void main(String[] args) throws InterruptedException {
MyService myService = new MyService();
ThreadA threadA = new ThreadA(myService);
ThreadB threadB = new ThreadB(myService);
threadA.setName("A线程");
threadB.setName("B线程");
threadA.start();
threadB.start();
Thread.sleep(1000);
myService.singalAll_A();
}
}
public class ThreadA extends Thread {
private MyService myService;
public ThreadA(MyService myService) {
this.myService = myService;
}
@Override
public void run() {
super.run();
myService.methodA();
}
}
public class ThreadB extends Thread {
private MyService myService;
public ThreadB(MyService myService) {
this.myService = myService;
}
@Override
public void run() {
super.run();
myService.methodB();
}
}
?
运行结果如下: begin methodA : A线程 begin methodB : B线程 singalAll_A:main end methodA : A线程
?可以看到,我们实现了选择性的唤醒某个线程。
原文:http://tanjie090508.iteye.com/blog/2288132