java多线程之同步锁(Lock) Bertha 。 2022-05-17 13:19 246阅读 0赞 从Java5开始,提供了Lock, Lock提供了比synchronized方法和synchronized代码块更广泛的锁定操作,Lock可以实现更灵活的结构,并且支持多个相关的Condition对象(对象监视器)。 Lock是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应先获得Lock对象。 示例代码: ReentrantLockTest类: public class ReentrantLockTest { private final ReentrantLock lock = new ReentrantLock(); //创建10个线程 public void userPrint() { for (int i = 0; i < 10; i++) { new Thread(new Runnable() { public void run() { print(); } }).start(); } } public void print() { lock.lock(); System.out.println("线程" + Thread.currentThread().getName() + "正在使用打印机"); try { Thread.sleep(new Random().nextInt(1000)); System.out.println("线程" + Thread.currentThread().getName() + "资源使用打印机"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //获取等待得到同步锁的线程个数 System.out.println("还剩 " + lock.getQueueLength() + "人要使用打印机"); lock.unlock(); } } Main类: public class Main { public static void main(String[] args) throws Exception { new ReentrantLockTest().userPrint(); } 测试结果: ![70][] 可以看到我们创建的10个线程并没有同时进来使用打印机方法,而是每次至进入一个线程使用打印机。 **Lock操作多个Condition对象:** 实例代码: ReentrantLockTest类: public class ReentrantLockTest { private final ReentrantLock lock = new ReentrantLock(); private Condition conditionA = lock.newCondition(); private Condition conditionB = lock.newCondition(); public void waitA() { lock.lock(); try { System.out.println(Thread.currentThread().getName() + "等待条件"); conditionA.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } lock.unlock(); } public void waitB() { lock.lock(); try { System.out.println(Thread.currentThread().getName() + "等待条件(没有人唤醒我,我将一直等待..)"); conditionB.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } lock.unlock(); } public void signal() throws InterruptedException { lock.lock(); Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + "执行完毕,唤醒A"); conditionA.signal(); lock.unlock(); } public void condition() throws InterruptedException { new Thread(new Runnable() { public void run() { waitA(); } }).start(); new Thread(new Runnable() { public void run() { waitB(); } }).start(); new Thread(new Runnable() { public void run() { try { signal(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); } } Mian类: public class Main { public static void main(String[] args) throws Exception { new ReentrantLockTest().condition(); } 测试结果: ![70 1][] 上例中,我们可以看到我们创建了两个Condition对象,并且启动了三个线程,waitA和waitB方法都在其中一个线程执行,但是signal方法只唤醒了持有ConditionA的方法,而另一个waitB方法将一直等待被唤醒。使用Condition可以进行线程间的通信。 [70]: /images/20220517/7f0e2c2ecbea447fb204aeb37e8488c9.png [70 1]: /images/20220517/d05b877ff2e94d259653466c5f520fe0.png
还没有评论,来说两句吧...