线程与并发 - JUC

多线程与高并发
  • juc - java.util.concurrent 包下java为我们提供了多种基于cas实现的线程安全锁
  • ReentrantLock - 可重入锁 需要手动释放锁
  • CountDownLatch - 倒数门栓
  • CyclicBarrier - 循环栅栏
  • Phaser - 阶段栅栏
  • ReadWriteLock - 读写锁 读锁共享 写锁排他
  • Semaphore - 信号灯
  • Exchanger - 线程交换器
  • LockSupport - 工具类,创建锁和其它同步工具类的基本线程阻塞原语
ReentrantLock
public class Thread_018 {
	//默认创建的是非公平锁
    Lock lock = new ReentrantLock();
    //new ReentrantLock(true); 创建公平锁
    //lock.newCondition(); 可以创建多个不同的等待队列

    boolean locakState = false;
    void m1(){
        try {
            lock.lock();//相当于 synchronized(this)
            for (int i = 0; i < 10; i++) {
                TimeUnit.SECONDS.sleep(1);
                System.out.println(i);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    void m2(){
        try {
            lock.lock();
            System.out.println("m2 start...");
        } finally {
            lock.unlock();
        }
    }

    void m3(){
        try {
        //tryLock 尝试获取锁不管锁定与否 程序都将继续执行
            locakState = lock.tryLock(5, TimeUnit.SECONDS);
            if(!locakState){
                System.out.println("尝试5s获取锁都没获取到,进行对应的业务处理");
            }else{
                System.out.println("m3 start......");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if(locakState){
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) {
        Thread_018 t = new Thread_018();
        new Thread(t::m1).start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(t::m2).start();
        //new Thread(t::m3).start();
    }
}

面试题:synchronized 与 ReentrantLock 的区别?
答:synchronized:系统自动加锁、解锁,不可以出现多个同的等待队列,默认进行四种锁状态的升级
ReentrantLock:需要手动加锁、解锁,可以出现多个不同的等待队列、cas实现

CountDownLatch
/**
* latch 就是 我规定一批线程的数量,下一批线程来了想要执行必须要等待
* 我这一批的latch倒数到0即所有线程执行完毕 门栓打开 下一批线程才可以进来
*/
public class Thread_023 {
    public static void main(String[] args) {
        countDown();
    }

    public static void countDown(){
        Thread[] threads = new Thread[100];
        CountDownLatch cdl = new CountDownLatch(threads.length);

        for (int i = 0; i < 100; i++) {
            threads[i] = new Thread(()->{
                int result = 0;
                for (int j = 0; j < 1000; j++) {
                    result ++;
                }
                //每个线程执行完毕之后需要对latch进行countDown操作
                cdl.countDown();
            },"t"+i);
        }

        for (int i = 0; i < 100; i++) {
            threads[i].start();
        }

        try {
        	//门栓阻塞 需要倒数到0 才能继续执行
            cdl.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("end");
    }
}
CyclicBarrier
/**
 * 需要等待设定的所有资源到齐后栅栏打开,程序执行;随后栅栏重新起来再等待执行
 */
public class Thread_024 {
    public static void main(String[] args) {
        CyclicBarrier cyc = new CyclicBarrier(3,()-> System.out.println("资源填充完毕!准备发射!"));

        for (int i = 0; i < 30; i++) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            new Thread(()->{
                try {
                    cyc.await();
                    System.out.println(Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }

            },"t"+i).start();
        }
    }

}
Phaser
/**
 * 按照不同的阶段对线程进行执行 首先批量注册线程数量 
 * 在不同的阶段对线程是否向下运行进行不同操作
 */
public class Thread_025 {
    static Random ran = new Random();
    static Phaser phaser = new MarryPhaser();

    public static void main(String[] args) {
    //批量注册需要执行的线程数量
        phaser.bulkRegister(7);
        for (int i = 0; i < 5; i++) {
            new Thread(new Person("p"+i)).start();
        }
        new Thread(new Person("新郎")).start();
        new Thread(new Person("新娘")).start();
    }

//继承Phaser 并对每个阶段进行不同操作
    static class MarryPhaser extends Phaser{
        @Override
        protected boolean onAdvance(int phase, int registeredParties) {
            switch (phase){
                case 0:
                    System.out.println("所有人都到齐了 准备开饭!"+registeredParties);
                    return false;
                case 1:
                    System.out.println("所有人都吃完了 准备离场!"+registeredParties);
                    return false;
                case 2:
                    System.out.println("所有人都离场了 新郎新娘准备洞房!"+registeredParties);
                    return false;
                case 3:
                    System.out.println("新郎新娘makeBaby!"+registeredParties);
                    return true;
                default:
                    return true;
            }
        }
    }

    static class Person implements Runnable{
        private String name;
        public Person(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            arrive();//0阶段 按顺序排
            eat();//1阶段
            leave();//2阶段
            makeBaby();//3阶段
        }

        void arrive() {
            waitSeconds(ran.nextInt(10));
            System.out.println(name + "到达婚礼现场!");
            // 到达并等待向前 线程已经到达这个阶段并执行 等待其它线程完成一同向前
            phaser.arriveAndAwaitAdvance();
        }

        void eat(){
            waitSeconds(ran.nextInt(10));
            System.out.println(name +"吃好喝好!");
            phaser.arriveAndAwaitAdvance();
        }

        void leave(){
            waitSeconds(ran.nextInt(10));
            System.out.println(name +"吃完离开!");
            phaser.arriveAndAwaitAdvance();
        }

        void makeBaby(){
            waitSeconds(ran.nextInt(10));
            if("新郎".equals(name) || "新娘".equals(name)){
                waitSeconds(ran.nextInt(10));
                System.out.println("make baby"+name);
                phaser.arriveAndAwaitAdvance();
            }else{
            //根据不同的业务 对线程进行注销操作bulkRegister的数量会相应的跟随减少 促使其它线程可继续执行
                phaser.arriveAndDeregister();
            }
        }
    }


    static void waitSeconds(int second){
        try {
            TimeUnit.SECONDS.sleep(second);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
ReadWriteLock
/**
 * 读写锁 保证读是共享锁 写是排他锁 保证读取的内容都是一样的
 */
public class Thread_026 {

    static ReadWriteLock lock = new ReentrantReadWriteLock();
    static Lock readLock = lock.readLock();
    static Lock writeLock = lock.writeLock();
    private static int value = 8;

    static int read(Lock lock){
        try {
            lock.lock();
            System.out.println("read over value is : "+value);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return value;
    }

    static void write(Lock lock,int v){
        try {
            lock.lock();
            value = v;
            System.out.println("write over value is : "+value);
        } finally {
            lock.unlock();
        }
    }

    static void sleep(int sec){
        try {
            TimeUnit.SECONDS.sleep(sec);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Runnable read = () -> read(readLock);
        Runnable write = () -> write(writeLock, new Random().nextInt(100));

        for (int i = 0; i < 3; i++) {
            new Thread(write).start();
        }

        for (int i = 0; i < 10; i++) {
            new Thread(read).start();
        }
    }
}
Semaphore
/**
 * Semaphore含义是限流
 * 往Semaphore里面传一个数 --> 允许通过的数量
 */
public class Thread_027 {

    //创建一个 允许一个permit通过的Semaphore 默认创建非公平锁
    //new Semaphore(1,true); 创建公平锁
    static Semaphore semaphore = new Semaphore(1);

    static void read(){
        try {
            //阻塞方法 我如果获取不到permit我就阻塞再这里
            semaphore.acquire();
            System.out.println(Thread.currentThread().getName()+" is running");
            sleep(5);
            System.out.println(Thread.currentThread().getName()+" is over");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //返还通过许可 相当于释放锁
            semaphore.release();
        }
    }

    static void sleep(int sec){
        try {
            TimeUnit.SECONDS.sleep(sec);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Runnable read = () -> read();
        for (int i = 1; i < 7; i++) {
//            semaphore.drainPermits();
            new Thread(read,"t"+i).start();
        }
    }
}
Exchanger
/**
 * Exchanger 交换器 两个线程间通讯 交换数据
 */
public class Thread_029 {
    static Exchanger exchanger = new Exchanger();

    public static void main(String[] args) {
        new Thread(()->{
            int num = 10;
            try {
                num = Integer.parseInt(exchanger.exchange(num)+"");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("t1 num is : " + num);
        }).start();

        new Thread(()->{
            int num = 100;
            try {
                num = Integer.parseInt(exchanger.exchange(num)+"");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("t2 num is : "+num);
        }).start();
    }
}
LockSupport
/**
 * LockSupport 线程的唤醒和阻塞
 */
public class Thread_030 {

    public static void main(String[] args) {
        Thread t = new Thread(()->{
            for (int i = 0; i < 10; i++) {
                System.out.println(i);
                if(i == 5){
                    //阻塞线程
                    LockSupport.park();
                }
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
        //唤醒线程 需要指定唤醒哪一个线程
        //LockSupport.unpark(t);
    }
}

你可能感兴趣的:(我与Java相爱相杀的这些年)