一、使用ReentrantLock类
除了Synchronized达到现场之间同步互斥外,还可以使用ReentrantLock类
也能达到同样的效果,其在扩展功能上也更加强大,比如有嗅探锁定,
多路分支通知等功能,使用上也比Synchronized 更灵活。
(一)、ReentrantLock类 使用
package com.it.po.thread11; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class MyService { private Lock lock =new ReentrantLock(); public void testMethod(){ lock.lock();//加锁 for(int i=0;i<5;i++){ String name = Thread.currentThread().getName(); System.out.println("线程 "+name+" "+(i+1)); } lock.unlock();//释放锁 } }
package com.it.po.thread11; public class MyThread1 extends Thread { private MyService myService; public MyThread1(MyService myService) { this.myService = myService; } @Override public void run() { super.run(); myService.testMethod(); } }
package com.it.po.thread11; import com.it.po.thread10.*; public class Run1 { public static void main(String[] args) throws InterruptedException { MyService myService = new MyService(); MyThread1 my1 = new MyThread1(myService); MyThread1 my2 = new MyThread1(myService); MyThread1 my3 = new MyThread1(myService); MyThread1 my4 = new MyThread1(myService); my1.setName("A "); my2.setName("B "); my3.setName("C "); my4.setName("D "); my1.start(); my2.start(); my3.start(); my4.start(); } }
线程 C 1 线程 C 2 线程 C 3 线程 C 4 线程 C 5 线程 B 1 线程 B 2 线程 B 3 线程 B 4 线程 B 5 线程 A 1 线程 A 2 线程 A 3 线程 A 4 线程 A 5 线程 D 1 线程 D 2 线程 D 3 线程 D 4 线程 D 5
当前线程打印完成之后释放锁,其他线程才可以打印
(二)、
Lock 线程同步
package com.it.po.thread11; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class MyService2 { private Lock lock =new ReentrantLock(); public void methodA(){ try { lock.lock();//加锁 String name = Thread.currentThread().getName(); System.out.println("methodA begin 线程 "+name+" time= "+System.currentTimeMillis()); Thread.sleep(5000); System.out.println("methodA end 线程 "+name+" time= "+System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock();//释放锁 } } public void methodB(){ try { lock.lock();//加锁 String name = Thread.currentThread().getName(); System.out.println("methodB begin 线程 "+name+" time= "+System.currentTimeMillis()); Thread.sleep(5000); System.out.println("methodB end 线程 "+name+" time= "+System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock();//释放锁 } } }


package com.it.po.thread11; public class Run2 { public static void main(String[] args) throws InterruptedException { MyService2 myService = new MyService2(); MyThread2_1 my1 = new MyThread2_1(myService); MyThread2_2 my2 = new MyThread2_2(myService); MyThread2_3 my3 = new MyThread2_3(myService); MyThread2_4 my4 = new MyThread2_4(myService); my1.setName("A "); my2.setName("B "); my3.setName("C "); my4.setName("D "); my1.start(); my2.start(); my3.start(); my4.start(); } }
methodA begin 线程 A time= 1575471578684 methodA end 线程 A time= 1575471583686 methodA begin 线程 B time= 1575471583686 methodA end 线程 B time= 1575471588686 methodB begin 线程 D time= 1575471588686 methodB end 线程 D time= 1575471593686 methodB begin 线程 C time= 1575471593686 methodB end 线程 C time= 1575471598686
(三)奇怪的不同步
package com.it.po.thread11; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class MyService2 { private Lock lock =new ReentrantLock(); public void methodA(){ try { lock.lock();//加锁 String name = Thread.currentThread().getName(); System.out.println("methodA begin 线程 "+name+" time= "+System.currentTimeMillis()); Thread.sleep(5000); System.out.println("methodA end 线程 "+name+" time= "+System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock();//释放锁 } } public void methodB(){ try { lock.lock();//加锁 String name = Thread.currentThread().getName(); System.out.println("methodB begin 线程 "+name+" time= "+System.currentTimeMillis()); Thread.sleep(5000); System.out.println("methodB end 线程 "+name+" time= "+System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock();//释放锁 } } synchronized public void methodC(){ try { String name = Thread.currentThread().getName(); System.out.println("methodC begin 线程 "+name+" time= "+System.currentTimeMillis()); Thread.sleep(5000); System.out.println("methodC end 线程 "+name+" time= "+System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } }
package com.it.po.thread11; public class MyThread2_5 extends Thread { private MyService2 myService2; public MyThread2_5(MyService2 myService2) { this.myService2 = myService2; } @Override public void run() { super.run(); myService2.methodC(); } }
package com.it.po.thread11; public class Run2 { public static void main(String[] args) throws InterruptedException { MyService2 myService = new MyService2(); MyThread2_1 my1 = new MyThread2_1(myService); MyThread2_2 my2 = new MyThread2_2(myService); MyThread2_3 my3 = new MyThread2_3(myService); MyThread2_4 my4 = new MyThread2_4(myService); MyThread2_5 my5 = new MyThread2_5(myService); my1.setName("A "); my2.setName("B "); my3.setName("C "); my4.setName("D "); my5.setName("E "); my1.start(); my2.start(); my3.start(); my4.start(); my5.start(); } }
methodA begin 线程 A time= 1575472866023 methodC begin 线程 E time= 1575472866023 methodA end 线程 A time= 1575472871023 methodA begin 线程 B time= 1575472871023 methodC end 线程 E time= 1575472871024 methodA end 线程 B time= 1575472876024 methodB begin 线程 C time= 1575472876024 methodB end 线程 C time= 1575472881024 methodB begin 线程 D time= 1575472881024 methodB end 线程 D time= 1575472886024
结论:
1、调用lock.lock();代码的线程就持有了 “ 对象监视器” ,其他线程只有等待
2.lock.lock() 和 synchronized 锁 不一样导致不同步。
浙公网安备 33010602011771号