线程中常用的工具

CountDownLatch

//计数器
public class CountDownLatch_Demo {
    // 线程
    private static ExecutorService executor = Executors.newFixedThreadPool(9);
    // 计数器(一般是与线程数量相同,也可多于线程)
    private static final CountDownLatch latch = new CountDownLatch(9);
    public static void main(String[]args) throws InterruptedException{
        //串行模拟获取数据
        int [] data = query();
        //并行处理
        for(int i=0;i

CyclicBarrier

//人满发车,还差一位。
public class CyclicBarrier_Demo{
    public static void main(String[]args) throws InterruptedException{
        CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
        Thread t1 = new Thread(){
            public void run(){
                try {
                    Thread.sleep(1500);
                    System.out.println("T1休眠了1.5秒");
                    cyclicBarrier.await();
                    System.out.println("T1工作完成");
                }catch (InterruptedException e){
                    e.printStackTrace();
                }catch (BrokenBarrierException e){
                    e.printStackTrace();
                }
            }
        };
        Thread t2 = new Thread(){
          public void run(){
              try {
                  Thread.sleep(4500);
                  System.out.println("T休眠了4.5秒");
                  cyclicBarrier.await();
                  System.out.println("T2工作完成");
              }catch (InterruptedException e){
                  e.printStackTrace();
              }catch (BrokenBarrierException e){
                  e.printStackTrace();
              }
          }
        };
            t1.start();
            t2.start();
        // 复位
        cyclicBarrier.reset();
        System.out.println("main线程休眠10秒");
        TimeUnit.SECONDS.sleep(10);
        Thread t3 = new Thread(){
            public void run(){
                try {
                    Thread.sleep(2500);
                    System.out.println("T3休眠了2.5秒");
                    cyclicBarrier.await();
                    System.out.println("T3工作完成");
                }catch (InterruptedException e){
                    e.printStackTrace();
                }catch (BrokenBarrierException e){
                    e.printStackTrace();
                }
            }
        };
        Thread t4 = new Thread(){
            public void run(){
                try {
                    Thread.sleep(5000);
                    System.out.println("T4休眠了5秒");
                    cyclicBarrier.await();
                    System.out.println("T4工作完成");
                }catch (InterruptedException e){
                    e.printStackTrace();
                }catch (BrokenBarrierException e){
                    e.printStackTrace();
                }
            }
        };
        t3.start();
        t4.start();
    }
}

Phase

// 阶段器(一个阶段的结束是下一个阶段的开始)
public class Phase_Demo {
    public static void main(String[]args) {
        final Phaser phaser = new Phaser(5);
        for (int i=1;i<6;i++){
            new Athletes(i,phaser){}.start();
        }
    }
    
    static class Athletes extends Thread{
        private final int no;
        private final Phaser phaser;
        Athletes(int no, Phaser phaser){
            this.no=no;
            this.phaser = phaser;
        }
        @Override
        public void run(){
            try {
                System.out.println(no+":号运动员开始跑步");
                TimeUnit.SECONDS.sleep(1);
                System.out.println(no+":号运动员跑步结束");
                phaser.arriveAndAwaitAdvance();

                TimeUnit.SECONDS.sleep(3);
                System.out.println(no+":号运动员开始骑车");
                TimeUnit.SECONDS.sleep(1);
                System.out.println(no+":号运动员骑车结束");
                phaser.arriveAndAwaitAdvance();

                TimeUnit.SECONDS.sleep(1);
                System.out.println(no+":号运动员开始游泳");
                TimeUnit.SECONDS.sleep(1);
                System.out.println(no+":号运动员游泳结束");
                phaser.arriveAndAwaitAdvance();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

Exchanger

//两两交换器
public class Exchanger_Demo {
    public static void main(String[]args)throws InterruptedException{
        final Exchanger exchanger = new Exchanger<>();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    String result = exchanger.exchange("我来自T1");
                    System.out.println(Thread.currentThread().getName()+"线程获的的value:"+result);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        },"T1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    String result = exchanger.exchange("我来自T2");
                    System.out.println(Thread.currentThread().getName()+"线程获的的value:"+result);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        },"T2");
        t1.start();
        t2.start();
    }
}

Semaphore

// 当前的的节奏大师
public class Semaphore_Demo {
	/*
// 创建具有给定的许可数和非公平的公平设置的 Semaphore。
        Semaphore(int permits)
// 创建具有给定的许可数和给定的公平设置的 Semaphore。
        Semaphore(int permits, boolean fair)
// 从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。
        void acquire()
// 从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞,或者线程已被中断。
        void acquire(int permits)
// 从此信号量中获取许可,在有可用的许可前将其阻塞。
        void acquireUninterruptibly()
// 从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞。
        void acquireUninterruptibly(int permits)
// 返回此信号量中当前可用的许可数。
        int availablePermits()
// 获取并返回立即可用的所有许可。
        int drainPermits()
// 返回一个 collection,包含可能等待获取的线程。
        protected Collection getQueuedThreads()
// 返回正在等待获取的线程的估计数目。
        int getQueueLength()
// 查询是否有线程正在等待获取。
        boolean hasQueuedThreads()
// 如果此信号量的公平设置为 true,则返回 true。
        boolean isFair()
// 根据指定的缩减量减小可用许可的数目。
        protected void reducePermits(int reduction)
// 释放一个许可,将其返回给信号量。
        void release()
// 释放给定数目的许可,将其返回到信号量。
        void release(int permits)
// 返回标识此信号量的字符串,以及信号量的状态。
        String toString()
// 仅在调用时此信号量存在一个可用许可,才从信号量获取许可。
        boolean tryAcquire()
// 仅在调用时此信号量中有给定数目的许可时,才从此信号量中获取这些许可。
        boolean tryAcquire(int permits)
// 如果在给定的等待时间内此信号量有可用的所有许可,并且当前线程未被中断,则从此信号量获取给定数目的许可。
        boolean tryAcquire(int permits, long timeout, TimeUnit unit)
// 如果在给定的等待时间内,此信号量有可用的许可并且当前线程未被中断,则从此信号量获取一个许可。
        boolean tryAcquire(long timeout, TimeUnit unit)
*/
    public static void main(String[]args){
        Semaphore semaphore = new Semaphore(2);
        Thread t1 = new Thread(){
            public void run(){
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"开始工作");
                    Thread.sleep(1000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }finally {
                    semaphore.release();
                    System.out.println(Thread.currentThread().getName()+"开始unlock.");
                }
            }
        };
        Thread t2 = new Thread(){
            public void run(){
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"开始工作.");
                    Thread.sleep(8000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }finally {
                    semaphore.release();
                    System.out.println(Thread.currentThread().getName()+"开始unlock.");
                }
            }
        };
        t1.start();
        t2.start();
    }
}

ReentrantLock

// Lock的实现接口
public class ReentrantLock_Demo {
 /*  获取锁,若当前lock被其他线程获取;则此线程阻塞等待lock被释放
     如果采用Lock,必须主动去释放锁,并且在发生异常时,不会自动释放锁
    void lock();

     获取锁,若当前锁不可用(被其他线程获取);
     则阻塞线程,等待获取锁,则这个线程能够响应中断,即中断线程的等待状态
    void lockInterruptibly() throws InterruptedException;

     来尝试获取锁,如果获取成功,则返回true;
     如果获取失败(即锁已被其他线程获取),则返回false
     也就是说,这个方法无论如何都会立即返回
    boolean tryLock();

     在拿不到锁时会等待一定的时间
     等待过程中,可以被中断
     超过时间,依然获取不到,则返回false;否则返回true
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

     释放锁
    void unlock();

     返回一个绑定该lock的Condtion对象
     在Condition#await()之前,锁会被该线程持有
     Condition#await() 会自动释放锁,在wait返回之后,会自动获取锁
     Condition newCondition();  */
    //公平锁:先来先服务的原则
    //非公平锁保证:无法保证新线程抢占已经在排队的线程的锁。
    private static final Lock LOCK = new ReentrantLock(true);
    public static void main(String[]args) throws InterruptedException{

        Thread t1 = new Thread(){
            public void run(){
                needLock();
           //     testUnInterruptibly();
            }
        };
        Thread t2 = new Thread(){
            public void run(){
                needLock();
            //    testUnInterruptibly();
            }
        };
        t1.start();
        TimeUnit.SECONDS.sleep(2);
        t1.interrupt();
        TimeUnit.SECONDS.sleep(2);
        t2.start();

    }

    public static void testUnInterruptibly(){
        try {
            LOCK.lockInterruptibly();
            System.out.println(Thread.currentThread().getName() + "拿到锁");
            TimeUnit.SECONDS.sleep(10);
            }catch (InterruptedException e){
            System.out.println(Thread.currentThread().getName() + "被打断A");
            //   e.printStackTrace();
            System.out.println(Thread.currentThread().getName() + "被打断B");
             }finally {
                LOCK.unlock();
                System.out.println(Thread.currentThread().getName()+"释放锁");
        }
    }
    public static void needLock(){
        try {
            LOCK.lock();
            System.out.println(Thread.currentThread().getName()+"拿到锁");
            TimeUnit.SECONDS.sleep(2);
        }catch (InterruptedException e){
        }finally {
            LOCK.unlock();
            System.out.println(Thread.currentThread().getName()+"释放锁");
        }
    }
}

ReadWriterLock

// 读写锁
public class ReadWriterLock_Demo {
    private final static ReentrantReadWriteLock ReadWriteLock = new ReentrantReadWriteLock(true);
    private final static Lock readLock = ReadWriteLock.readLock();
    private final static Lock writeLock = ReadWriteLock.writeLock();
    private final static List data = new ArrayList<>();

    public static void main(String[]args) throws InterruptedException{
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (;;)write();
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (;;)
                reader();
            }
        });
        t1.start();
        TimeUnit.SECONDS.sleep(1);
        t2.start();
    }

    public static void write(){
        try {
            writeLock.lock();
            try {
                TimeUnit.SECONDS.sleep(1);
            }catch (InterruptedException e){
            }

         data.add(System.currentTimeMillis());
        }finally {
            writeLock.unlock();
        }
    }

    public static void reader(){
        try {
            readLock.lock();
            try {
                TimeUnit.SECONDS.sleep(1);
            }catch (InterruptedException e){
            }
            System.out.println(Thread.currentThread().getName()+"读线程"+data.size());
        }finally {
            readLock.unlock();
        }
    }
}

StampedLock

// 读写锁的改进,8推出来的,可以避免写的线程饿死。
public class StampedLock_Demo1 {
    private final static StampedLock lock = new StampedLock();
    private final static List data = new ArrayList<>();
    public static void main(String[]args){
        final ExecutorService executor = Executors.newFixedThreadPool(6);
        Runnable readTask = () ->{
            while (true){
                read();
            }
        };
        Runnable writeTask = () ->{
            for (;;){
                write();
            }
        };
        executor.submit(readTask);
        executor.submit(readTask);
        executor.submit(readTask);
        executor.submit(readTask);
        executor.submit(readTask);
        executor.submit(writeTask);
    }
    private static void read(){
        long stamped = -1;
        try {
            stamped = lock.readLock();
          //  data.stream().forEach(System.out::println);
            System.out.println(Thread.currentThread().getName()+"读线程,stamped: "+stamped);
            TimeUnit.SECONDS.sleep(1);
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            lock.unlockRead(stamped);
        }
    }
    private static void write(){
        long stamped = -1;
        try {
            stamped = lock.writeLock();
            data.add(System.currentTimeMillis());
            System.out.println(Thread.currentThread().getName()+":写线程,stamped: "+stamped);
            TimeUnit.SECONDS.sleep(1);
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            lock.unlockWrite(stamped);
        }
    }
}

// 对读锁乐观点
public class StampedLock_Demo2 {
    private final static StampedLock lock = new StampedLock();
    private final static List data = new ArrayList<>();
    public static void main(String[]args){
        final ExecutorService executor = Executors.newFixedThreadPool(7);
        Runnable readTask = () ->{
            while (true){
                read();
            }
        };
        Runnable writeTask = () ->{
            for (;;){
                write();
            }
        };
        executor.submit(readTask);
        executor.submit(readTask);
        executor.submit(readTask);
        executor.submit(readTask);
        executor.submit(readTask);
        executor.submit(readTask);
        executor.submit(writeTask);
    }
    private static void read(){
        long stamp = lock.tryOptimisticRead();
        if (lock.validate(stamp)){
            try {
                stamp = lock.readLock();
                TimeUnit.SECONDS.sleep(1);
                //data.stream().forEach(System.out::println);
                System.out.println(Thread.currentThread().getName()+"读线程,stamp: "+stamp);
            }catch (InterruptedException e){
                e.printStackTrace();
            }finally {
                lock.unlockRead(stamp);
            }
        }
    }
    private static void write(){
        long stamp = -1;
        try {
            stamp = lock.writeLock();
            data.add(System.currentTimeMillis());
            System.out.println(Thread.currentThread().getName()+"写线程,stamped: "+stamp);
            TimeUnit.SECONDS.sleep(1);
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            lock.unlockWrite(stamp);
        }
    }
}

 

Condition

//线程间的通信
public class Condition_Demo1 {
    private final static ReentrantLock LOCK = new ReentrantLock();
    private final static Condition CONDITION = LOCK.newCondition();
    private static AtomicInteger data = new AtomicInteger(0);
    private static AtomicBoolean noUse =new AtomicBoolean(false);
    public static void main(String [] args)throws InterruptedException{
        Thread p1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for(;;){
                    buildData();
               }
            }
        });

        Thread c1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (;;){
                    userData();
                }
            }
        });
        Thread c2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (;;){
                    userData();
                }
            }
        });
        p1.start();
        TimeUnit.SECONDS.sleep(2);
        c1.start();
        c2.start();
    }

    private  static void buildData(){
        try {
            LOCK.lock();  //synchronized begin
            while (noUse.get()){
                CONDITION.await();   // monitor.wait()
            }
            int numb = data.addAndGet(2);
            System.out.println(Thread.currentThread().getName()+": 线程生产了2个,库存: "+numb);
            TimeUnit.SECONDS.sleep(1);
            noUse.set(true);
            CONDITION.signalAll();       // monitor.notifyall()
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            LOCK.unlock();       // sycnhronized end
        }
    }

    private static void userData(){
        try {
            LOCK.lock();
            while (!noUse.get()){
                CONDITION.await();
            }
            TimeUnit.SECONDS.sleep(1);
            int numb = data.decrementAndGet();
            System.out.println(Thread.currentThread().getName()+": 线程消费1个,剩余: "+numb);
            noUse.set(false);
            CONDITION.signalAll();
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            LOCK.unlock();
        }
    }
}


public class Condition_Demo2 {
    private final static Lock lock = new ReentrantLock();
    private final static Condition produceCond = lock.newCondition();
    private final static Condition consumeCond = lock.newCondition();
    private final static LinkedList TimeStamp_Pool = new LinkedList<>();
    private final static int MAX_Capacity = 100;
    public static void main(String[]args){
        Thread P1 =new Thread(new Runnable() {
            @Override
            public void run() {
                for (;;)produce();
            }
        });
        Thread P2 =new Thread(new Runnable() {
            @Override
            public void run() {
                  for (;;) produce();
            }
        });
        Thread C1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (;;) cusume();
            }
        });
        Thread C2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for(;;) cusume();
            }
        });
        P1.start();
        P2.start();
        C1.start();
        C2.start();
    }
    private static void produce(){
        try {
            lock.lock();
            TimeUnit.SECONDS.sleep(1);
            while (TimeStamp_Pool.size()>=MAX_Capacity){
               produceCond.await();
            }
            long value = System.currentTimeMillis();
            System.out.println(Thread.currentThread().getName()+" 线程,添加"+value+"到 TimeStamp_Pool");
            TimeStamp_Pool.addLast(value);
            consumeCond.signalAll();
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    private static void cusume(){
        try {
            lock.lock();
            TimeUnit.SECONDS.sleep(1);
            while (TimeStamp_Pool.isEmpty()){
                consumeCond.await();
            }
            long value = TimeStamp_Pool.removeFirst();
            System.out.println(Thread.currentThread().getName()+" 线程,消费了"+value);
            produceCond.signalAll();
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}

 

你可能感兴趣的:(多线程,Java基础)