多线程 - 11.线程关键字的实现类

ReentrantLock 锁类

RenntrantLock.java 在扩展功能上比 synchronized 强很多,它具备嗅探锁定、多路分支通知等相关功能。

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class MyService{
    private Lock lock = new ReentrantLock();
    public void myMethod() {
        lock.lock();
        for (int i = 0; i < 3; i++) {
            System.out.println("ThreadName=" + Thread.currentThread().getName() + ", 第" + (i+1) + "进入函数");
        }
        lock.unlock();
    }
}

class ThreadA extends Thread{
    private MyService myService;
    public ThreadA(MyService myService){
        super();
        this.myService = myService;
    }

    @Override
    public void run() {
        super.run();
        myService.myMethod();
    }
}

public class test0 {
    public static void main(String[] args) {
        MyService myService = new MyService();
        Thread a = new ThreadA(myService);
        a.start();
        Thread b = new ThreadA(myService);
        b.start();
        Thread c = new ThreadA(myService);
        c.start();
    }
}

ThreadName=Thread-0, 第1进入函数
ThreadName=Thread-0, 第2进入函数
ThreadName=Thread-0, 第3进入函数
ThreadName=Thread-2, 第1进入函数
ThreadName=Thread-2, 第2进入函数
ThreadName=Thread-2, 第3进入函数
ThreadName=Thread-1, 第1进入函数
ThreadName=Thread-1, 第2进入函数
ThreadName=Thread-1, 第3进入函数

Lock 接口的函数定义

  1. void lock(); : 获得锁。
  2. void unlock(); : 松开锁。
  3. boolean tryLock();: 只有在调用时锁是空闲的情况下才获取锁。
  4. boolean tryLock(long time, TimeUnit unit) throws InterruptedException; : 如果锁在给定的等待时间内空闲并且当前线程未被 interrupt / interrupted标记,则获取该锁。
  5. Condition newCondition(); : 返回绑定到此 lock() 实例的新 Condition 实例。
  6. void lockInterruptibly() throws InterruptedException; : 获取锁,除非当前线程是被 interrupt / interrupted 标记过的。

Lock 接口的实现类

  1. ReadLock
  2. ReadLockView
  3. ReentrantLock
  4. WriteLock
  5. WriteLockView
Condition.java 监视器接口类

关键字 synchronized 与 wait() / notify() / notifyAll()方法相结合可以实现等待 / 通知模式, ReentrantLock 也可以实现同样的通能,但是需要借助于 Condition 对象。
Condition 监视器接口类的函数定义

  1. void await() throws InterruptedException;使当前线程等待,直到发出唤醒或触发 interrupt / interrupted 标记。
  2. boolean await(long time, TimeUnit unit) throws InterruptedException;使当前线程等待,直到发出信号或被中断,或者指定的等待时间结束。
  3. long awaitNanos(long nanosTimeout) throws InterruptedException;使当前线程等待,直到发出信号或被中断,或者指定的等待时间结束。
  4. void awaitUninterruptibly(); : 使当前线程等待直到发出信号。
  5. boolean awaitUntil(Date deadline) throws InterruptedException; : 使当前线程等待,直到发出信号或被中断,或者指定的截止时间过去。
  6. void signal(); : 唤醒一个等待线程。
  7. void signalAll(); : 唤醒全部等待线程。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class MyService{
    private Lock lock = new ReentrantLock();
    public Condition condition = lock.newCondition();

    public void await() {
        lock.lock();
        System.out.println("await 时间为:" + System.currentTimeMillis());
        try {
            condition.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void signal() {
        try {
            lock.lock();
            System.out.println("Signal 时间为:" + System.currentTimeMillis());
            condition.signal();
        } finally {
            lock.unlock();
        }
    }
}

class ThreadA extends Thread{
    private MyService myService;

    public ThreadA(MyService myService) {
        super();
        this.myService = myService;
    }

    @Override
    public void run() {
        super.run();
        myService.await();
    }
}

public class test0 {

    public static void main(String[] args) {
        MyService myService = new MyService();
        ThreadA a = new ThreadA(myService);
        a.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        myService.signal();
    }
}

await 时间为:1592453263834
Signal 时间为:1592453264833

所谓单个唤醒,即是在某类中设置多个 Condition ,并且只唤醒其中一个。

猜你喜欢

转载自blog.csdn.net/weixin_43845524/article/details/106826785