Lock的使用(六)——使用ReentrantLock类

1.方法awaitUninterruptibly()的使用

  创建名称为4.1.14的项目,类Service.java代码如下:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Service {
    private ReentrantLock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    public void testMethod() {
        try {
            lock.lock();
            System.out.println("wait begin");
            condition.await();
            System.out.println("wait   end");
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.out.println("catch");
        } finally {
            lock.unlock();
        }
    }
}

线程类MyThread.java代码如下:

public class MyThread extends Thread {
    private Service service;
    public MyThread(Service service) {
        super();
        this.service = service;
    }
    @Override
    public void run() {
        service.testMethod();
    }
}

运行类Run.java代码如下:

public class Run {
    public static void main(String[] args) {
        try {
            Service service = new Service();
            MyThread myThread = new MyThread(service);
            myThread.start();
            Thread.sleep(3000);
            myThread.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

程序运行后出现异常,这是正常现象。结果如下所示:

wait begin
java.lang.InterruptedException
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.reportInterruptAfterWait(AbstractQueuedSynchronizer.java:2017)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2052)
	at Service.testMethod(Service.java:10)
	at MyThread.run(MyThread.java:9)
catch

更改Service.java代码如下:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Service {
    private ReentrantLock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    public void testMethod() {
        try {
            lock.lock();
            System.out.println("wait begin");
            condition.awaitUninterruptibly();
            System.out.println("wait   end");
        } finally {
            lock.unlock();
        }
    }
}

程序运行后的结果如下:

wait begin

正常运行并没有报错

2.方法awaitUntil()的用法

创建项目4.1.15,两个线程类代码如下:
MyThreadA.java

public class MyThreadA  extends Thread {
    private Service service;
    public MyThreadA(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.waitMethod();
    }
}

MyThreadB.java

public class MyThreadB extends Thread {
    private Service service;
    public MyThreadB(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.waitMethod();
    }
}

类Service.java代码如下:

import java.util.Calendar;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Service {
    private ReentrantLock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    public void waitMethod() {
        try {
            Calendar calendarRef = Calendar.getInstance();
            calendarRef.add(Calendar.SECOND, 10);
            lock.lock();
            System.out.println("wait begin timer="+System.currentTimeMillis());
            condition.awaitUntil(calendarRef.getTime());
            System.out.println("wait end timer="+System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    public void notifyMethod() {
        try {
            Calendar calendarRef = Calendar.getInstance();
            calendarRef.add(Calendar.SECOND, 10);
            lock.lock();
            System.out.println("notify begin timer="+System.currentTimeMillis());
            condition.signalAll();
            System.out.println("notify end timer="+System.currentTimeMillis());
        } finally {
            lock.unlock();
        }
    }
}

创建运行类Run1.java代码如下:

public class Run1 {
    public static void main(String[] args) throws InterruptedException {
        Service service = new Service();
        MyThreadA myThreadA = new MyThreadA(service);
        myThreadA.start();
    }
}

程序运行结果如下所示:

wait begin timer=1661399159557
wait end timer=1661399169561

10秒后自动唤醒自己

创建运行类Run2.java代码如下:

public class Run2 {
    public static void main(String[] args) throws InterruptedException {
        Service service = new Service();
        MyThreadA myThreadA = new MyThreadA(service);
        myThreadA.start();
        Thread.sleep(2000);
        MyThreadB myThreadB = new MyThreadB(service);
        myThreadB.start();
    }
}

运行结果如下所示:

wait begin timer=1661414500822
wait begin timer=1661414502808
wait end timer=1661414510828
wait end timer=1661414512815

2秒后被其他线程所唤醒

  说明线程在等待时间到达前,可以被其他线程提前唤醒。

3.使用Condition实现顺序执行

  使用Condition对象可以对线程执行的业务进行排序规划。
创建项目4.1.16,类F.java代码如下:

public class F {
    volatile public static int nextPrintWho = 1;
}

创建运行类Run.java代码如下:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Run {
    volatile private static int nextPrintWho = 1;
    private static ReentrantLock lock = new ReentrantLock();
    final private static Condition conditionA = lock.newCondition();
    final private static Condition conditionB = lock.newCondition();
    final private static Condition conditionC = lock.newCondition();
    public static void main(String[] args) {
        Thread threadA = new Thread() {
            public void run() {
                try {
                    lock.lock();
                    while (nextPrintWho != 1) {
                        conditionA.await();
                    }
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadA" + (i + 1));
                    }
                    nextPrintWho = 2;
                    conditionB.signalAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };
        Thread threadB = new Thread() {
            public void run() {
                try {
                    lock.lock();
                    while (nextPrintWho != 2) {
                        conditionB.await();
                    }
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadB" + (i + 1));
                    }
                    nextPrintWho = 3;
                    conditionC.signalAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                finally {
                    lock.unlock();
                }
            }
        };
        Thread threadC = new Thread() {
            public  void  run() {
                try {
                    lock.lock();
                    while (nextPrintWho != 3) {
                        conditionC.await();
                    }
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadC" + (i + 1));
                    }
                    nextPrintWho = 1;
                    conditionA.signalAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };
        Thread[] aArray = new Thread[5];
        Thread[] bArray = new Thread[5];
        Thread[] cArray = new Thread[5];
        for (int i = 0; i < 5; i++) {
            aArray[i] = new Thread(threadA);
            bArray[i] = new Thread(threadB);
            cArray[i] = new Thread(threadC);
            aArray[i].start();
            bArray[i].start();
            cArray[i].start();
        }
    }
}

程序运行结果如下所示:

ThreadA1
ThreadA2
ThreadA3
ThreadB1
ThreadB2
ThreadB3
ThreadC1
ThreadC2
ThreadC3
ThreadA1
ThreadA2
ThreadA3
ThreadB1
ThreadB2
ThreadB3
ThreadC1
ThreadC2
ThreadC3
ThreadA1
ThreadA2
ThreadA3
ThreadB1
ThreadB2
ThreadB3
ThreadC1
ThreadC2
ThreadC3
ThreadA1
ThreadA2
ThreadA3
ThreadB1
ThreadB2
ThreadB3
ThreadC1
ThreadC2
ThreadC3
ThreadA1
ThreadA2
ThreadA3
ThreadB1
ThreadB2
ThreadB3
ThreadC1
ThreadC2
ThreadC3

按顺序打印


以上代码下载请点击该链接:https://github.com/Yarrow052/Java-package.git

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ReentrantLockJava中的一个可重入锁,它提供了比synchronized更灵活的锁定机制。tryLock()是ReentrantLock中的一个方法,用于尝试获取锁。如果锁可用,则获取锁并立即返回true;如果锁不可用,则立即返回false,而不会阻塞线程。 使用tryLock()方法时需要注意以下几点: 1. 如果tryLock()返回true,表示当前线程成功获取到了锁,可以执行临界区代码。 2. 如果tryLock()返回false,表示当前锁被其他线程占用,当前线程没有获取到锁,可以根据需要选择等待一段时间再次尝试获取锁,或者放弃获取锁执行其他操作。 3. 可以使用tryLock(long timeout, TimeUnit unit)方法,在指定的时间范围内尝试获取锁,如果在指定时间内获取到了锁,则返回true;如果超时仍未获取到锁,则返回false。 使用ReentrantLock tryLock()的示例代码如下: ```java import java.util.concurrent.locks.ReentrantLock; public class TryLockExample { private static ReentrantLock lock = new ReentrantLock(); public static void main(String[] args) { Thread thread1 = new Thread(() -> { if (lock.tryLock()) { try { System.out.println("Thread 1 acquired the lock"); // 执行临界区代码 } finally { lock.unlock(); } } else { System.out.println("Thread 1 failed to acquire the lock"); } }); Thread thread2 = new Thread(() -> { if (lock.tryLock()) { try { System.out.println("Thread 2 acquired the lock"); // 执行临界区代码 } finally { lock.unlock(); } } else { System.out.println("Thread 2 failed to acquire the lock"); } }); thread1.start(); thread2.start(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值