一:使用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