多线程编程之Lock(ReentrantLock)的使用

在多线程编程中,使用synchronized关键字实现线程的等待和通知,不能够通知特定的线程,所以不够灵活,所以java中还提供了另外一种锁
ReentrantLock(可重入锁),它配合Condition(对象监视器)使用可以实现特定线程的等待和唤醒。

package ReentrantLock;

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

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

    public void awaitMethod() {
        try {
            lock.lock();
            System.out.println("A");
            condition.await();
            System.out.println("B");

        }catch(InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
            System.out.println("锁释放了");
        }
    }
}

package ReentrantLock;

public class ThreadA extends Thread{
    private MyService service;
    public ThreadA(MyService service) {
        super();
        this.service=service;
    }
    public void run() {
        service.awaitMethod();
    }

}

package ReentrantLock;

public class run {
    public static void main(String[] args) {
        MyService service=new MyService();
        ThreadA a=new ThreadA(service);
        a.start();
    }

}
//控制台输出A,但是线程还在等待,不能够输出B

上面的这段代码是对ReentrantLock的简单测试,看ReentrantLock是否具有锁的功能。

继续看:

package ReentrantLock1;

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

public class Service {
    private ReentrantLock lock=new ReentrantLock();
    Condition condition = lock.newCondition();
    public void await() {
        try {
            lock.lock();
            System.out.println("await 的时间为:"+System.currentTimeMillis());
            condition.await();

        }catch(InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void signal() {
        try {
            lock.lock();
            System.out.println("sigal 的时间为:"+System.currentTimeMillis());
            condition.signal();

        }finally {
            lock.unlock();

        }
    }

}

package ReentrantLock1;

public class ThreadA extends Thread{
    Service service ;
    public ThreadA(Service service) {
        super();
        this.service=service;
    }
    public void run() {
        service.await();
    }

}

package ReentrantLock1;

public class Run {
    public static void main(String[] args) {

        try {
            Service service =new Service();
            ThreadA a=new ThreadA(service);
            a.start();
            Thread.sleep(3000);
            service.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
//控制台输出:
//await 的时间为:1508549198801
//sigal 的时间为:1508549201808
//线程A进行等待,三秒过后主线程对其唤醒,线程结束。

以上代码测试的是线程等待与唤醒(和synchronized的关键字和wait,notify的用法基本一样)。

我们来看看如何利用Condition实现指定线程的唤醒,在这之前我们先来看一个错误的版本:

package ReentrantLock2;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Service {
    private Lock lock = new ReentrantLock();
    public Condition condition = lock.newCondition();
    public void awaitA() {
        try {
            lock.lock();
            System.out.println("begin awaitA 时间为:"+System.currentTimeMillis());
            condition.await();
            System.out.println("end awaitA 时间为:"+System.currentTimeMillis());
        }catch(InterruptedException e) {
            e.printStackTrace();

        }finally {
            lock.unlock();

        }

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

        }finally {
            lock.unlock();

        }

    }

    public void signalAll() {
        try {
            lock.lock();
            System.out.println("signalAll 时间为:"+System.currentTimeMillis());
            condition.signalAll();

        }finally {
            lock.unlock();

        }


    }

}

package ReentrantLock2;

public class ThreadA extends Thread {
    private Service service;
    public ThreadA(Service service) {
        super();
        this.service=service;
    }
    public void run() {
        service.awaitA();
    }
}

package ReentrantLock2;

public class ThreadB extends Thread {
    private Service service;
    public ThreadB(Service service) {
        super();
        this.service=service;
    }
    public void run() {
        service.awaitB();
    }
}

package ReentrantLock2;

public class run {
    public static void main(String[] args) {
        try {
            Service service = new Service();
            ThreadA a = new ThreadA(service);
            a.start();
            Thread.sleep(1000);
            ThreadB b = new ThreadB(service);
            b.start();
            Thread.sleep(3000);
            service.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
//控制台输出:
//begin awaitA 时间为:1508550421648
//begin awaitB 时间为:1508550422648
//signalAll 时间为:1508550425647
//end awaitA 时间为:1508550425647
//end awaitB 时间为:1508550425647

我们可以很容易看出,主线程调用signalAll将所有的线程唤醒了。

上例中只定义了一个Condition,其实我们只要定义多个Condition就可以实现指定线程的唤醒了:

package ReentrantLock3;

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

public class Service {
    private ReentrantLock lock = new ReentrantLock();
    public Condition conditionA = lock.newCondition();
    public Condition conditionB = lock.newCondition();
    public void awaitA() {

        try {
            lock.lock();
            System.out.println("begin awaitA 的时间为:"+System.currentTimeMillis()+"ThreadName="+Thread.currentThread().getName());
            conditionA.await();
            System.out.println("end awaitA 的时间为:"+System.currentTimeMillis()+"ThreadName="+Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }   
    }

    public void awaitB() {

        try {
            lock.lock();
            System.out.println("begin awaitB 的时间为:"+System.currentTimeMillis()+"ThreadName="+Thread.currentThread().getName());
            conditionB.await();
            System.out.println("end awaitB 的时间为:"+System.currentTimeMillis()+"ThreadName="+Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }   
    }

    public void signalAll_A() {
        try {
            lock.lock();
            System.out.println("signalAll_A时间为:"+System.currentTimeMillis()+"线程名:"+Thread.currentThread().getName());
            conditionA.signalAll();
        }finally {
            lock.unlock();
        }
    }

    public void signalAll_B() {
        try {
            lock.lock();
            System.out.println("signalAll_B时间为:"+System.currentTimeMillis()+"线程名:"+Thread.currentThread().getName());
            conditionA.signalAll();
        }finally {
            lock.unlock();
        }
    }
}

package ReentrantLock3;

public class ThreadA extends Thread{
    private Service service;
    public ThreadA(Service service) {
        super();
        this.service=service;
    }
    public void run() {
        service.awaitA();
    }

}

package ReentrantLock3;

public class ThreadB extends Thread{
    private Service service;
    public ThreadB(Service service) {
        super();
        this.service=service;
    }
    public void run() {
        service.awaitB();
    }
}

package ReentrantLock3;

public class Run {
    public static void main(String[] args) throws InterruptedException {
            Service service = new Service();
            ThreadA a = new ThreadA(service);
            a.setName("A");
            a.start();

            ThreadB b = new ThreadB(service);
            b.setName("B");
            b.start();

            Thread.sleep(3000);
            service.signalAll_A();


    }

}

//控制台输出:
//begin awaitA 的时间为:1508550671233ThreadName=A
//begin awaitB 的时间为:1508550671233ThreadName=B
//signalAll_A时间为:1508550674233线程名:main
//end awaitA 的时间为:1508550674233ThreadName=A

上面代码Service中定义了conditionA和conditionB,这样我们分别调用Condition对象就可以对指定的线程唤醒。

使用ReentrantLock,condition可以实现synchronized完成的一切操作:
例如交替运行(生产者和消费者),

package ReentrantLock4;

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();
    private boolean hasValue=false;
    public void set() {
        try {
            lock.lock();
            while(hasValue==true) {
                condition.await();
            }
            System.out.println("打印☆");
            hasValue=true;
            condition.signal();


        }catch(InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    public void get() {
        try {
            lock.lock();
            while(hasValue==false) {
                condition.await();
            }
            System.out.println("打印△");
            hasValue=false;
            condition.signal();

        }catch(InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }

    }

}
//省略了线程A,B类,和主方法。

同时也可以实现多生产者多消费者,但是要将signal方法更改为signalAll方法,这样才不可能出现假死。

下面将公平锁和非公平锁,公平锁就是按队列排队,先到的线程先获得锁,非公平锁先到不一定获得锁。

package fairAndfairless;

import java.util.concurrent.locks.ReentrantLock;

public class Service {
    private ReentrantLock lock;
    public Service(boolean isfair) {
        lock=new ReentrantLock(isfair);
    }
    public void ServiceMethod() {
        try {
            lock.lock();
            System.out.println(Thread.currentThread().getName()+"线程获得锁定");

        }finally {
            lock.unlock();
        }
    }

}

package fairAndfairless;

public class test {
    public static void main(String[] args) {
        final Service service = new Service(true);
        Runnable runnable = new Runnable() {
            public void run() {
                System.out.println("线程"+Thread.currentThread().getName()+"运行了");
                service.ServiceMethod();
            }
        };
        Thread[] threadArray = new Thread[10];
        for(int i=0;i<10;i++) {
            threadArray[i] = new Thread(runnable);
        }
        for(int i=0;i<10;i++) {
            threadArray[i].start();
        }
    }


}

//控制台输出:
//线程Thread-0运行了
//线程Thread-4运行了
//线程Thread-3运行了
//Thread-4线程获得锁定
//Thread-0线程获得锁定
//线程Thread-7运行了
//线程Thread-1运行了
//线程Thread-2运行了
//线程Thread-8运行了
//线程Thread-5运行了
//线程Thread-6运行了
//Thread-3线程获得锁定
//线程Thread-9运行了
//Thread-7线程获得锁定
//Thread-1线程获得锁定
//Thread-2线程获得锁定
//Thread-8线程获得锁定
//Thread-5线程获得锁定
//Thread-6线程获得锁定
//Thread-9线程获得锁定

从控制台输出我们可以看出先启动的线程基本上先获得锁。
如果我们将test中代码改为:final Service service = new Service(false);
控制台输出:

线程Thread-0运行了
线程Thread-5运行了
Thread-0线程获得锁定
线程Thread-3运行了
线程Thread-2运行了
线程Thread-1运行了
线程Thread-4运行了
线程Thread-8运行了
Thread-5线程获得锁定
线程Thread-7运行了
Thread-3线程获得锁定
Thread-2线程获得锁定
线程Thread-6运行了
线程Thread-9运行了
Thread-6线程获得锁定
Thread-1线程获得锁定
Thread-4线程获得锁定
Thread-8线程获得锁定
Thread-7线程获得锁定
Thread-9线程获得锁定

观察我们发现好多线程并不按顺序获得锁。


下面我们来看看ReentrantLock对象的一些方法:
getHoldCount:返回当前线程保持此锁定的个数,也就是调用lock()方法的次数。

package getHoldCount;
//测试当前调用lock方法的次数
import java.util.concurrent.locks.ReentrantLock;
public class Service {
    private ReentrantLock lock =new ReentrantLock();
    public void ServiceMethod1() {
        try {
            lock.lock();
            System.out.println("调用lock方法的次数:"+lock.getHoldCount());
            ServiceMethod2();

        }finally {
            lock.unlock();
        }
    }
    public void ServiceMethod2() {
        try {
            lock.lock();
            System.out.println("调用lock的次数:"+lock.getHoldCount());
        }finally {
            lock.unlock();
        }

    }

}

package getHoldCount;

public class run {
    public static void main(String[] args) {
        Service service = new Service();
        service.ServiceMethod1();
    }

}
//控制台输出:
//调用lock方法的次数:1
//调用lock的次数:2

int getQueueLength(),返回正在等待获取此锁定的线程 估计数

package getQueueLength;

import java.util.concurrent.locks.ReentrantLock;

public class Service {
    public  ReentrantLock lock = new ReentrantLock();
    public void serviceMethod() {
        try {
            lock.lock();
            System.out.println("线程"+Thread.currentThread().getName()+"进入方法");
            Thread.sleep(Integer.MAX_VALUE);
        }catch(InterruptedException e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

}   

package getQueueLength;
//测试getQueueLength方法
public class run {
    public static void main(String[] args) throws InterruptedException {
        final  Service service = new Service();
        Runnable runnable = new Runnable() {
            public void run() {
                service.serviceMethod();
            }
        };
        Thread[] threadArray = new Thread[10];
        for(int i=0;i<10;i++) {
            threadArray[i]=new Thread(runnable);
        }
        for(int i=0;i<10;i++) {
            threadArray[i].start();
        }
        Thread.sleep(2000);
        System.out.println("有"+service.lock.getQueueLength());

    }

}
//控制台输出:
//线程Thread-0进入方法
//有9

int getWaitQueuelength(Condition condition),返回此锁定相关的给定条件Condition的线程估计数

package getWaitQueueLength;

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

public class Service {
    private ReentrantLock lock = new ReentrantLock();
    Condition newCondition=lock.newCondition();
    public void waitMethod() {
        try {
            lock.lock();
            newCondition.await();

        }catch(InterruptedException e) {
            e.printStackTrace();

        }finally {
            lock.unlock();

        }

    }
    public void nitifyMethod() {
        try {
            lock.lock();
            System.out.println("有"+lock.getWaitQueueLength(newCondition)+"个线程在等待newCondition");
    }finally {
        lock.unlock();
    }

}
}

package getWaitQueueLength;

//测试getWaitQueueLength(Condition condition)
public class run {
    public static void main(String[] args) throws InterruptedException {
        final  Service service = new Service();
        Runnable runnable = new Runnable() {
            public void run() {
                service.waitMethod();
            }
        };
        Thread[] threadArray = new Thread[10];
        for(int i=0;i<10;i++) {
            threadArray[i]=new Thread(runnable);
        }
        for(int i=0;i<10;i++) {
            threadArray[i].start();
        }
        Thread.sleep(2000);
        service.nitifyMethod();

    }

}

//控制台输出:
//有10个线程在等待newCondition

boolean hasQueueedThread(Thread thread):查询指定线程是否正在等待获取此锁定
boolean hasQueueThreads():查询是否有线程正在等待获取此锁定

package hasQueueedThread;

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

public class Service {
    public ReentrantLock lock = new ReentrantLock();
    public Condition condition = lock.newCondition();
    public void waitMethod() {
        try {
            lock.lock();
            Thread.sleep(Integer.MAX_VALUE);

        }catch(InterruptedException e) {
            e.printStackTrace();

        }finally {
            lock.unlock();
        }
    }


}

package hasQueueedThread;
//测试hasQueueedThread和hasQueuedThread
public class run {
    public static void main(String[] args) throws InterruptedException {
        final Service service = new Service();
        Runnable runnable = new Runnable() {
            public void run() {
                service.waitMethod();
            }

        };
        Thread a = new Thread(runnable);
        a.start();
        Thread.sleep(500);
        Thread b= new Thread(runnable);
        b.start();
        Thread.sleep(500);
        System.out.println(service.lock.hasQueuedThread(a));
        System.out.println(service.lock.hasQueuedThread(b));
        System.out.println(service.lock.hasQueuedThreads());
    }


}
//控制台输出:
//false
//true
//true

boolean has waiters(Condition condition):查询是否有线程正在等待与此锁定有关的condition条件。

package hasWaiters;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Service {
    public ReentrantLock lock = new ReentrantLock();
    public Condition condition = lock.newCondition();
    public void waitMethod() {
        try {
            lock.lock();
            condition.await();


        }catch(InterruptedException e) {
            e.printStackTrace();

        }finally {
            lock.unlock();
        }
    }
    public void notifyMethod() {
        try {
            lock.lock();
            System.out.println("是否有线程正在等待condition"+lock.hasWaiters(condition)+"数量是多少?"+lock.getWaitQueueLength(condition));
            condition.signal();;


        }finally {
            lock.unlock();
        }
    }


}

package hasWaiters;

//测试hasWaiters(Condition condition)方法
public class run {
    public static void main(String[] args) throws InterruptedException {
        final  Service service = new Service();
        Runnable runnable = new Runnable() {
            public void run() {
                service.waitMethod();
            }
        };
        Thread[] threadArray = new Thread[10];
        for(int i=0;i<10;i++) {
            threadArray[i]=new Thread(runnable);
        }
        for(int i=0;i<10;i++) {
            threadArray[i].start();
        }
        Thread.sleep(2000);
        service.notifyMethod();

    }

}
//控制台输出:
//是否有线程正在等待condition true  数量是多少?10

boolean isFair():判断是否是公平锁。
boolean isHeldByCurrentThread():查询当前线程是否保持此锁定。
boolean isLocked():查询此锁定是否由任意线程保持。

void lockInterruptibly():如果当前线程未中断则获取锁定,如果已经中断则出现异常。

package lockInterruptibly;

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

public class Service {
    ReentrantLock lock = new ReentrantLock();
    Condition condition = lock.newCondition();
    public void waitMethod(){
        try{
            lock.lockInterruptibly();;
            System.out.println("lock begin"+Thread.currentThread().getName());
            for(int i=0;i<Integer.MAX_VALUE/10;i++){
                Math.random();
            }
            System.out.println("lock end"+Thread.currentThread().getName());


        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            if(lock.isHeldByCurrentThread())
            lock.unlock();
        }
    }

}

package lockInterruptibly;

public class test {
    public static void main(String[] args) throws InterruptedException {
        final Service service = new Service();
        Runnable runnable = new Runnable(){
            public void run(){
                service.waitMethod();
            }

        };
        Thread a= new Thread(runnable);
        a.setName("A");
        a.start();
        Thread.sleep(500);
        Thread b = new Thread(runnable);
        b.setName("B");
        b.start();
        b.interrupt();
        System.out.println("main end");
    }

}

boolean tryLock():仅在调用时,锁未被另一个线程保持的情况下,才获取该锁定。

package tryLock;

import java.util.concurrent.locks.ReentrantLock;

public class Service {
    ReentrantLock lock = new ReentrantLock();
    public void waitMethod(){
        if(lock.tryLock()){
            System.out.println("achieve lock");

        }else{
            System.out.println("not achieve lock");
        }
    }

}

package tryLock;
//验证tryLock
public class test {
    public static void main(String[] args) {
        final Service service = new Service();
        Runnable runnable = new Runnable(){
            public void run(){
                service.waitMethod();
            }
        };
        Thread a = new Thread(runnable);
        a.setName("A");
        a.start();
        Thread b = new Thread(runnable);
        b.setName("B");
        b.start();

    }

}

boolean tryLock(long timeout,TimeUnit unit):如果锁定在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁定。

package tryLock;

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

public class Service2 {
    public ReentrantLock lock = new ReentrantLock();
    public void waitMethod(){
        try{
            if(lock.tryLock(3, TimeUnit.SECONDS)) {
                System.out.println("   "+Thread.currentThread().getName()+"获得锁的时间为"+System.currentTimeMillis());
                Thread.sleep(10000);
            }else {
                System.out.println("  "+Thread.currentThread().getName()+"没有获得锁");
            }

        }catch(InterruptedException e){
            e.printStackTrace();

        }finally{
            if(lock.isHeldByCurrentThread())
            lock.unlock();
        }

    }

}

package tryLock;
//验证tryLock(3, TimeUnit.SECONDS)
public class test2 {
    public static void main(String[] args) {
        final Service2 service = new Service2();
        Runnable runnable = new Runnable(){
            public void run(){
                System.out.println(Thread.currentThread().getName()+"调用waitMethod的时间"+System.currentTimeMillis());
                service.waitMethod();
            }
        };
        Thread a = new Thread(runnable);
        a.setName("A");
        a.start();
        Thread b = new Thread(runnable);
        b.setName("B");
        b.start();

    }

}

awaitUninterruptibly():实现不可中断的条件等待。

package awaitUninterruptibly;

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

public class Service {
    private ReentrantLock lock = new ReentrantLock();
    Condition condition = lock.newCondition();
    public void waitMethod() {
        try {
                lock.lock();
                System.out.println("进入等待");
                condition.awaitUninterruptibly();
                System.out.println("等待结束");
        }finally {
            lock.unlock();
        }

        }       
}

package awaitUninterruptibly;


//测试awaitUninterruptibly()方法(实现不可中断的条件等待。 )
public class Run {
    public static void main(String[] args) throws InterruptedException {
        Service service = new Service();
        Runnable runnable = new Runnable() {
            public void run(){
                service.waitMethod();
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
        Thread.sleep(3000);
        thread.interrupt();

    }

}

awaitUntil(Date date),在等待指定时间后,自动唤醒。

package awaitUntil;

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 waitMehod() {
        try {
            Calendar calendar= Calendar.getInstance();
            calendar.add(Calendar.SECOND, 10);
            lock.lock();
            System.out.println("begin wait"+System.currentTimeMillis());
            condition.awaitUntil(calendar.getTime());
            System.out.println("end wait"+System.currentTimeMillis());

        }catch(InterruptedException e){
            e.printStackTrace();

        }finally {
            lock.lock();
        }


    }
    public void notifyMethod() {
        try {
            Calendar calendar= Calendar.getInstance();
            calendar.add(Calendar.SECOND, 10);
            lock.lock();
            System.out.println(" notify begin"+System.currentTimeMillis());
            condition.signalAll();
            System.out.println("notify end"+System.currentTimeMillis());
        }finally {
            lock.unlock();
        }

    }

}

package awaitUntil;
//测试awaitUntil(Date date),在等待指定时间后,自动唤醒。
public class Test {
    public static void main(String[] args) {
        Service service = new Service();
        Runnable runnable = new Runnable() {
            public void run() {
                service.waitMehod();
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }

}
package awaitUntil;
//测试awaitUntil(Date date),提前唤醒
public class Test2 {
    public static void main(String[] args) throws InterruptedException {
        Service service = new Service();
        Runnable runnable = new Runnable() {
            public void run() {
                service.waitMehod();
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
        Thread.sleep(2000);
        Runnable runnable1 = new Runnable() {
            public void run() {
                service.notifyMethod();
            }
        };
        Thread thread1 = new Thread(runnable1);
        thread1.start();
    }

}

下面用Condition实现顺序执行:

package ConditionSort;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
//用condition实现顺序打印
public class Run {
    volatile private static int nextprintwho=1;
    private static ReentrantLock lock = new ReentrantLock();
    final private static Condition condition1 = lock.newCondition();
    final private static Condition condition2 = lock.newCondition();
    final private static Condition condition3 = lock.newCondition();
    public static void main(String[] args) {
        Thread ThreadA = new Thread(){
            public void run() {
                try {
                    lock.lock();
                    if(nextprintwho!=1) {
                        condition1.await();
                    }
                    for(int i=0;i<3;i++) {
                        System.out.println(Thread.currentThread().getName()+(i+1));
                    }
                    nextprintwho=2;
                    condition2.signalAll();


                }catch(InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }

            }
        };

        Thread ThreadB = new Thread(){
            public void run() {
                try {
                    lock.lock();
                    if(nextprintwho!=2) {
                        condition1.await();
                    }
                    for(int i=0;i<3;i++) {
                        System.out.println(Thread.currentThread().getName()+(i+1));
                    }
                    nextprintwho=3;
                    condition3.signalAll();
                }catch(InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }

            }
        };

        Thread ThreadC = new Thread(){
            public void run() {
                try {
                    lock.lock();
                    if(nextprintwho!=3) {
                        condition1.await();
                    }
                    for(int i=0;i<3;i++) {
                        System.out.println(Thread.currentThread().getName()+(i+1));
                    }
                    nextprintwho=1;
                    condition1.signalAll();
                }catch(InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }

            }
        };
        ThreadA.setName("A");
        ThreadA.start();
        ThreadB.setName("B");
        ThreadB.start();
        ThreadC.setName("C");
        ThreadC.start();

    }

}
输出:
A1
A2
A3
B1
B2
B3
C1
C2
C3

上面是我看书的一些书中代码,仅供自己查阅,不喜勿碰

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值