java多线程常用关键字与方法介绍(二)

来源:互联网 发布:java调用c语言dll csdn 编辑:程序博客网 时间:2024/06/10 07:29

  • 一ReentrantLock类
  • 二ReentrantReadWriteLock类
  • 三Condition

一、ReentrantLock类

服务类:

public class MyService {    private Lock lock = new ReentrantLock();    public void methodA() {        lock.lock();        for (int i = 0; i < 10; i++) {            System.out.println(Thread.currentThread().getName() + "-" + i);        }        lock.unlock();    }}

线程类

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

调用类

public class Main {    public static void main(String[] args){        MyService myService = new MyService();        MyThread myThread1 = new MyThread(myService);        MyThread myThread2 = new MyThread(myService);        MyThread myThread3 = new MyThread(myService);        myThread1.start();        myThread2.start();        myThread3.start();    }}

说明:

ReentrantLock的lock.lock()方法与synchronized 关键词以及Object.lock()效果类似。myThread1 与myThread2 与 myThread3 同步运行。 既然ReentrantLock与Object.lock()都是显示的调用锁,那么他俩有什么区别呢?ReentrantLock是JDK1.5之后才出现的类,他自然比Object.lock()更加进步。首先要解释一下“公平锁”与“非公平锁”的概念,当一个线程获取锁后获得执行机会,其他的线程尝试获取该锁时,发现锁被占用,因此进入等待队列。“非公平锁”机制就是当获得锁的线程执行完毕释放锁之后,JVM会在等待队列中随机挑选一个等待线程给他获取锁的机会,而“公平锁”机制就是JVM会在等待队列中挑选队头的线程给他获取锁的机会,也就是FIFO先进先出的顺序。公平锁:private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);非公平锁(默认就是):private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false);

二、ReentrantReadWriteLock类

public class MyService {    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();    public void read() {        try {            lock.readLock().lock();            System.out.println("获得读锁" + Thread.currentThread().getName() + "-" + System.currentTimeMillis());            Thread.sleep(5000);        }catch (InterruptedException e){            e.printStackTrace();        }finally {            lock.readLock().unlock();        }    }    public void write(){        try {            lock.writeLock().lock();            System.out.println("获得写锁" + Thread.currentThread().getName() + "-" + System.currentTimeMillis());            Thread.sleep(5000);        }catch (InterruptedException e){            e.printStackTrace();        }finally {            lock.writeLock().unlock();        }    }}

说明

读读共享、写写互斥、读写互斥。

三、Condition

public class MyService {    private ReentrantLock lock = new ReentrantLock();    public Condition conditionA = lock.newCondition();    public Condition conditionB = lock.newCondition();    public void methodA() {        try {            lock.lock();            conditionA.await();        }catch (InterruptedException e){            e.printStackTrace();        }finally {            lock.unlock();        }    }    public void methodB(){        try {            lock.lock();            conditionB.await();        }catch (InterruptedException e){            e.printStackTrace();        }finally {            lock.unlock();        }    }    public void signalAllA(){        try {            lock.lock();            conditionA.signalAll();        } finally {            lock.unlock();        }    }    public void signalAllB(){        try {            lock.lock();            conditionB.signalAll();        } finally {            lock.unlock();        }    }}

说明

在上一片博文[java多线程常用关键字与方法介绍(一)]中,提到wait()和notify()方法实现的等待/通知模式,而Condition 的await()和signal()方式也可以实现等待/通知模式。那么他俩有什么不一样呢?wait()和notify()是Object的方法,当多个线程中多个不同的方法调用wait()时,当新的线程调用notifyAll()时会唤醒所wait线程,但是当我们只想唤醒执行某一类方法的线程时,例如只想唤醒执行上述代码的methodA()方法的线程时,该怎么办呢?这时,我们的Condition类就派上用场了,一个Lock对象里可以创建多个Condition实例(即对象监视器),那么线程就可以注册在指定的Condition中,从而当多个线程进入wait时,可以更加精确的有选择性的唤醒某些线程。
0 0
原创粉丝点击