源无极

导航

 

一、使用Conditiuon实现顺序执行。

condition对象可以对线程执行的业务进行排序规则。

package com.it.po.thread11.thread11_1;

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

public class RunCondition {
    volatile private static int nextPrintWho=1;
    private static ReentrantLock lock =new ReentrantLock();
    private static Condition conditionA =lock.newCondition();
    private static Condition conditionB =lock.newCondition();
    private static Condition conditionC =lock.newCondition();
    public static void main(String[] args)  {
        Thread threadA = new Thread() {
            @Override
            public void run() {
                super.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() {
            @Override
            public void run() {
                super.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() {
            @Override
            public void run() {
                super.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[] t1 = new Thread[5];
        Thread[] t2 = new Thread[5];
        Thread[] t3 = new Thread[5];
        for(int i=0;i<5;i++){
            t1[i]=new Thread(threadA);
            t2[i]=new Thread(threadB);
            t3[i]=new Thread(threadC);
            t1[i].start();
            t2[i].start();
            t3[i].start();
        }
    }

}

 

threadA 1
threadA 2
threadA 3
threadB 1
threadB 2
threadB 3
threadC 1
threadC 2
threadC 3
threadA 1
threadA 2
threadA 3
threadB 1
threadB 2
threadB 3
threadC 1
threadC 2
threadC 3
threadA 1
threadA 2
threadA 3
threadB 1
threadB 2
threadB 3
threadC 1
threadC 2
threadC 3
threadA 1
threadA 2
threadA 3
threadB 1
threadB 2
threadB 3
threadC 1
threadC 2
threadC 3
threadA 1
threadA 2
threadA 3
threadB 1
threadB 2
threadB 3
threadC 1
threadC 2
threadC 3

 

 难点:分析执行顺序的原因。

 由于while 的关系,每次只有一个线程执行,另外两个wainting 

 二、使用ReentrantReadWriteLock类

ReentrantLock 类具有完全互斥排他的效果,即一时间只有一个线程

   在执行ReentrantLock.lock()方法后面的任务。

     这样做虽然保证了实例的线程安全,但是效率趋确是非常低下,所以,jdk提供了一种

读写锁ReentrantReadWriteLock 类,用它可以加快运行效率,在某一些不需要

操作实例变量的方法中,完全可以使用读写锁ReentrantReadWriteLock来

提升该方法的代码运行效率。

        读写锁也有两个锁,一个是读操作相关的锁,也叫共享锁。

另一个是写相关的锁,也叫排他锁。也就是多个读锁之间不排斥

而多个写锁之间会排斥,读和写锁也会排斥。

 同一时间多个锁读操作的可以都执行,写操作只有一个执行。

 (一)ReentrantReadWriteLock类 使用,读读共享。

package com.it.po.thread11.thread11_1;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Service14 {
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();
    }
}

}

 

 

 

package com.it.po.thread11.thread11_1;
public class Run14 {
    public static void main(String[] args) throws InterruptedException {
        Service14 service= new Service14();
        MyThread3_1 t1 = new MyThread3_1(service);
        MyThread3_2 t2 = new MyThread3_2(service);
        t1.setName("A");
        t2.setName("B");
        t1.start();
        t2.start();
    }

}
获得读锁 B 时间 1575728981271
获得读锁 A 时间 1575728981271

  (二)ReentrantReadWriteLock类 使用,写写互斥。

 

package com.it.po.thread11.thread11_1;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Service14 {
private ReentrantReadWriteLock lock =new ReentrantReadWriteLock();
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();
    }
}

}

 

 

获得读锁 A 时间 1575731808939
获得读锁 B 时间 1575731813939

 

   (三)ReentrantReadWriteLock类 使用,读写互斥。

 

package com.it.po.thread11.thread11_1;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Service14 {
private ReentrantReadWriteLock lock =new ReentrantReadWriteLock();
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();
    }
}
    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();
        }
    }

}

 

 

 

 

 

package com.it.po.thread11.thread11_1;
public class Run14 {
    public static void main(String[] args) throws InterruptedException {
        Service14 service= new Service14();
        MyThread3_1 t1 = new MyThread3_1(service);
        MyThread3_2 t2 = new MyThread3_2(service);
        t1.setName("A");
        t2.setName("B");
        t1.start();
        Thread.sleep(200);
        t2.start();
    }

}

 

获得读锁 A 时间 1575732030460
获得读锁 B 时间 1575732035460

 

 

    (四)ReentrantReadWriteLock类 使用,写读互斥。

package com.it.po.thread11.thread11_1;
public class Run14 {
    public static void main(String[] args) throws InterruptedException {
        Service14 service= new Service14();
        MyThread3_1 t1 = new MyThread3_1(service);
        MyThread3_2 t2 = new MyThread3_2(service);
        t1.setName("A");
        t2.setName("B");
        t2.start();
        Thread.sleep(200);
        t1.start();
    }

}

 

 

获得读锁 B 时间 1575732258069
获得读锁 A 时间 1575732263070

 

 

 

 

 

 

 

 

posted on 2019-12-07 22:31  源无极  阅读(158)  评论(0)    收藏  举报