JUC并发编程

1.什么是JUC

在这里插入图片描述在这里插入图片描述在这里插入图片描述

2.线程和进程

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

3.Lock锁(重点)

传统的synchronized锁

public class SaleTicketDemo01 {
    public static void main(String[] args) {
        //并发:多线程操作同一个资源,把资源类丢入线程
        Ticket ticket = new Ticket();
        //多线程操作
        new Thread(()->{
            for (int i = 0; i < 40; i++) {
                ticket.sale();
            }
        },"A").start();

        new Thread(()->{
            for (int i = 0; i < 40; i++) {
                ticket.sale();
            }
        },"B").start();

        new Thread(()->{
            for (int i = 0; i < 40; i++) {
                ticket.sale();
            }
        },"C").start();
    }
}

//资源类 OOP
class Ticket{
    //属性、方法
    private int number=30;

    //卖票的方法
    //synchronized 本质:队列,锁
    public synchronized void sale(){
        if(number>0){
            System.out.println(Thread.currentThread().getName()+"卖出了"+(number--)+"票,剩余:"+number);
        }
    }
}

在这里插入图片描述在这里插入图片描述在这里插入图片描述

public class SaleTicketDemo02 {
    public static void main(String[] args) {
        //并发:多线程操作同一个资源,把资源类丢入线程
        Ticket2 ticket = new Ticket2();
        //多线程操作
        new Thread(()->{for (int i = 0; i < 40; i++)ticket.sale();},"A").start();

        new Thread(()->{for (int i = 0; i < 40; i++)ticket.sale();},"B").start();

        new Thread(()->{for (int i = 0; i < 40; i++)ticket.sale();},"C").start();
    }
}

//资源类 OOP
class Ticket2{
    //属性、方法
    private int number=30;

    Lock lock=new ReentrantLock();

    //卖票的方法
    //synchronized 本质:队列,锁
    public  void sale(){

        lock.lock();//加锁

        try{
            //业务代码
            if(number>0){
                System.out.println(Thread.currentThread().getName()+"卖出了"+(number--)+"票,剩余:"+number);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock(); //解锁
        }
    }
}

在这里插入图片描述

4.生产者和消费者问题
public class A {
    public static void main(String[] args) {
        Data data = new Data();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"B").start();
    }
}
//判断等待,业务,通知
class Data{

    private int number=0;

    //+1
    public synchronized void increment() throws InterruptedException {
        if(number!=0){
            //等待
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName()+"==>"+number);
        //通知其他线程,我+1完毕了
        this.notifyAll();
    }

    //-1
    public synchronized void decrement() throws InterruptedException {
        if(number==0){
            //等待
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"==>"+number);
        //通知其他线程,我-1完毕了
        this.notifyAll();
    }
}

在这里插入图片描述
在这里插入图片描述

public class A {
    public static void main(String[] args) {
        Data data = new Data();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"B").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"C").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"D").start();
    }
}
//判断等待,业务,通知
class Data{

    private int number=0;

    //+1
    public synchronized void increment() throws InterruptedException {
        while(number!=0){
            //等待
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName()+"==>"+number);
        //通知其他线程,我+1完毕了
        this.notifyAll();
    }

    //-1
    public synchronized void decrement() throws InterruptedException {
        while (number==0){
            //等待
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"==>"+number);
        //通知其他线程,我-1完毕了
        this.notifyAll();
    }
}
5.JUC版的生产者和消费者问题

在这里插入图片描述在这里插入图片描述在这里插入图片描述

代码实现

public class B {
    public static void main(String[] args) {
        Data2 data = new Data2();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"B").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"C").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"D").start();
    }
}

//判断等待,业务,通知
class Data2{

    private int number=0;

    Lock lock=new ReentrantLock();
    Condition condition = lock.newCondition();

    //condition.await();
    //condition.signalAll();
    //
    
    //+1
    public  void increment() throws InterruptedException {
        lock.lock();
        try{
            while(number!=0){
                //等待
                condition.await();
            }
            number++;
            System.out.println(Thread.currentThread().getName()+"==>"+number);
            //通知其他线程,我+1完毕了
            condition.signalAll();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    //-1
    public  void decrement() throws InterruptedException {
        lock.lock();
       try{
           while (number==0){
               //等待
               condition.await();
           }
           number--;
           System.out.println(Thread.currentThread().getName()+"==>"+number);
           //通知其他线程,我-1完毕了
           condition.signalAll();
       }catch (Exception e){
            e.printStackTrace();
       }finally {
           lock.unlock();
       }
    }
}

在这里插入图片描述

A、B、C三个线程顺序执行

public class C {
    public static void main(String[] args) {
        Data3 data = new Data3();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.printA();
            }
        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.printB();
            }
        },"B").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.printC();
            }
        },"C").start();
    }
}
class Data3{

    private Lock lock=new ReentrantLock();
    private Condition condition1=lock.newCondition();
    private Condition condition2=lock.newCondition();
    private Condition condition3=lock.newCondition();
    private int number=1;//1A 2B 3C

    public void printA(){
        lock.lock();
        try {
            //业务,判断—>执行->通知
            while(number!=1){
                //等待
                condition1.await();
            }
            System.out.println(Thread.currentThread().getName()+"=>AAAAAA");
            //唤醒,唤醒指定的人,B
            number=2;
            condition2.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void printB(){
        lock.lock();
        try {
            //业务,判断—>执行->通知
            while(number!=2){
                //等待
                condition2.await();
            }
            System.out.println(Thread.currentThread().getName()+"=>BBBBBB");
            //唤醒,唤醒指定的人,B
            number=3;
            condition3.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void printC(){
        lock.lock();
        try {
            //业务,判断—>执行->通知
            while(number!=3){
                //等待
                condition3.await();
            }
            System.out.println(Thread.currentThread().getName()+"=>CCCCC");
            //唤醒,唤醒指定的人,C
            number=1;
            condition1.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
6.8锁问题

1.标准情况下,两个线程先打印发短信 还是打电话 1.发短信 2.打电话


/**
 * 8锁,就是关于锁的8个问题
 * 1.标准情况下,两个线程先打印发短信 还是打电话 1.发短信  2.打电话
 */
public class Test1 {
    public static void main(String[] args) {
        Phone phone = new Phone();

        new Thread(()->{
            phone.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone.call();
        },"B").start();
    }
}

class Phone{

    //synchronized 锁的对象是方法的调用者
    //两个方法用的是同一个锁,谁先拿到谁先执行
    public synchronized void sendSms(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public synchronized void call(){
        System.out.println("打电话");
    }
}

在这里插入图片描述

2.1标准情况下,两个线程先打印hello 还是打电话 1.hello 2.发短信

public class Test2 {
    public static void main(String[] args) {
        Phone2 phone = new Phone2();

        new Thread(()->{
            phone.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone.hello();
        },"B").start();
    }
}

class Phone2{

    //synchronized 锁的对象是方法的调用者
    //两个方法用的是同一个锁,谁先拿到谁先执行
    public synchronized void sendSms(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public synchronized void call(){
        System.out.println("打电话");
    }


    //这里没有锁!不是同步方法,不受锁的影响
    public  void hello(){
        System.out.println("hello");
    }
}

在这里插入图片描述

2.2标准情况下,两个对象两个线程先打印hello 还是打电话 1.hello 2.发短信

/**
 * 8锁,就是关于锁的8个问题
 * 1.标准情况下,两个线程先打印发短信 还是打电话 1.打电话  2.发短信
 */
public class Test2 {
    public static void main(String[] args) {
        Phone2 phone1 = new Phone2();
        Phone2 phone2 = new Phone2();

        new Thread(()->{
            phone1.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone2.call();
        },"B").start();
    }
}

class Phone2{

    //synchronized 锁的对象是方法的调用者
    //两个方法用的是同一个锁,谁先拿到谁先执行
    public synchronized void sendSms(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public synchronized void call(){
        System.out.println("打电话");
    }


    //这里没有锁!不是同步方法,不受锁的影响
    public  void hello(){
        System.out.println("hello");
    }
}

在这里插入图片描述

3.2标准情况下,两个对象两个线程先打印hello 还是打电话 1.hello 2.发短信

**
 * 8锁,就是关于锁的8个问题
 * 5.两个静态方法,两个线程先打印发短信 还是打电话 1.打电话  2.发短信
 */
public class Test3 {
    public static void main(String[] args) {
        Phone3 phone1 = new Phone3();
        Phone3 phone2 = new Phone3();

        new Thread(()->{
            phone1.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone2.call();
        },"B").start();
    }
}

class Phone3{

    //synchronized 锁的对象是方法的调用者
    //两个方法用的是同一个锁,谁先拿到谁先执行
    public static synchronized void sendSms(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public static synchronized void call(){
        System.out.println("打电话");
    }



}

在这里插入图片描述

3.3标准情况下,一个对象一个静态方法和一个普通方法先打印发短信 还是打电话 1.打电话2.发短信

/**
 * 8锁,就是关于锁的8个问题
 * 5.两个方法,两个线程先打印发短信 还是打电话 1.打电话  2.发短信
 */
public class Test4 {
    public static void main(String[] args) {
        Phone4 phone = new Phone4();

        new Thread(()->{
            phone.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone.call();
        },"B").start();
    }
}

class Phone4{

    //synchronized 锁的对象是方法的调用者
    //静态的同步方法,锁的是Class 类模板
    public static synchronized void sendSms(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    // 普通方法,锁的是调用者
    public  synchronized void call(){
        System.out.println("打电话");
    }



}

在这里插入图片描述

3.3标准情况下,两个对象一个静态方法和一个普通方法先打印发短信 还是打电话 1.打电话2.发短信

/**
 * 8锁,就是关于锁的8个问题
 * 6.两个方法,两个线程先打印发短信 还是打电话 1.打电话  2.发短信
 */
public class Test4 {
    public static void main(String[] args) {
        Phone4 phone1 = new Phone4();
        Phone4 phone2 = new Phone4();

        new Thread(()->{
            phone1.sendSms();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone2.call();
        },"B").start();
    }
}

class Phone4{

    //synchronized 锁的对象是方法的调用者
    //普通方法锁的是调用对象
    //静态的同步方法,锁的是Class 类模板,而一个类,只有一个类模板
    public static synchronized void sendSms(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    // 普通方法,锁的是调用者
    public  synchronized void call(){
        System.out.println("打电话");
    }



}

在这里插入图片描述在这里插入图片描述

7.集合类不安全
7.1.list,CopyOnWriteArrayList

在这里插入图片描述

7.2.set,CopyOnWriteArraySet

在这里插入图片描述 在这里插入图片描述

7.3.Map,ConcurrentHashMap

在这里插入图片描述在这里插入图片描述

8.Callable

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

9.常用的辅助类
9.1.CountDownLatch

在这里插入图片描述在这里插入图片描述在这里插入图片描述

9.2.CyclicBarrier

在这里插入图片描述在这里插入图片描述

9.3.Semaphore

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

10.读写锁.ReadWriteLock

在这里插入图片描述在这里插入图片描述


public class ReadWriteLockDemo {
    public static void main(String[] args) {
        MyCacheLock myCache = new MyCacheLock();

        //写入
        for (int i = 1; i <=5; i++) {
            final int temp=i;
            new Thread(()->{
                myCache.put(temp+"",temp+"");
            },String.valueOf(i)).start();
        }

        //读取
        for (int i = 1; i <=5; i++) {
            final int temp=i;
            new Thread(()->{
                myCache.get(temp+"");
            },String.valueOf(i)).start();
        }
    }
}

//加锁的
class MyCacheLock{
    private volatile Map<String,Object> map=new HashMap<>();
    //读写锁,更加细粒度的控制
    private ReadWriteLock readWriteLock=new ReentrantReadWriteLock();

    //存,写的时候,只希望只有一个线程写
    public void put(String key,Object value){
        readWriteLock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"写入"+key);
            map.put(key,value);
            System.out.println(Thread.currentThread().getName()+"写入OK");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }

    //取,读
    public void get(String key){
        readWriteLock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"读取"+key);
            Object o = map.get(key);
            System.out.println(Thread.currentThread().getName()+"读取OK");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.readLock().unlock();
        }
    }



}
/**
 * 自定义缓存
 */
class MyCache{
    private volatile Map<String,Object> map=new HashMap<>();

    //存,写
    public void put(String key,Object value){
        System.out.println(Thread.currentThread().getName()+"写入"+key);
        map.put(key,value);
        System.out.println(Thread.currentThread().getName()+"写入OK");
    }

    //取,读
    public void get(String key){
        System.out.println(Thread.currentThread().getName()+"读取"+key);
        Object o = map.get(key);
        System.out.println(Thread.currentThread().getName()+"读取OK");
    }



}

在这里插入图片描述

11.阻塞队列

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

1.add(),remove()
在这里插入图片描述
2.offer(),poll()
在这里插入图片描述在这里插入图片描述> 3.put(),take()
在这里插入图片描述> 4.offer(时间),poll(时间)

在这里插入图片描述

11.SynchronousQueue 同步队列

在这里插入图片描述在这里插入图片描述

public class SynchronousQueueDemo {
    public static void main(String[] args) {
        BlockingQueue<String> blockingQueue= new SynchronousQueue<>();//同步队列

        new Thread(()->{
            try{
                System.out.println(Thread.currentThread().getName()+"put 1");
                blockingQueue.put("1");
                System.out.println(Thread.currentThread().getName()+"put 2");
                blockingQueue.put("2");
                System.out.println(Thread.currentThread().getName()+"put 3");
                blockingQueue.put("3");
            }catch (Exception e){
                e.printStackTrace();
            }
        },"T1").start();

        new Thread(()->{
            try{
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+" get:"+blockingQueue.take());
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+" get:"+blockingQueue.take());
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+" get:"+blockingQueue.take());
            }catch (Exception e){
                e.printStackTrace();
            }
        },"T2").start();
    }
}

12.线程池(重点)

在这里插入图片描述在这里插入图片描述

三大方法

public class Demo01 {
    public static void main(String[] args) {
        //ExecutorService threadPool = Executors.newSingleThreadExecutor();//单个线程
        //ExecutorService threadPool = Executors.newFixedThreadPool(5);//创建一个固定的线程池大小
        ExecutorService threadPool = Executors.newCachedThreadPool();
        try{
            for (int i = 1; i <=100; i++) {
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+",ok");
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            threadPool.shutdown();
        }
    }
}

在这里插入图片描述

7大参数
分析源码

 public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

  public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }           

在这里插入图片描述在这里插入图片描述

public class Demo01 {
    public static void main(String[] args) {
        /*ExecutorService threadPool = Executors.newSingleThreadExecutor();//单个线程
        ExecutorService threadPool2 = Executors.newFixedThreadPool(5);//创建一个固定的线程池大小
        ExecutorService threadPool3 = Executors.newCachedThreadPool();*/

        ExecutorService threadPool = new ThreadPoolExecutor(
                2,
                5,
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),//候客区3个
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());//银行满了,还有人进来,不处理这个人的,抛出异常
                                                    //CallerRunsPolicy 哪来的,去哪里

        try{
            //最大承载: Deque + max
            //超过: java.util.concurrent.RejectedExecutionException
            for (int i = 1; i <=9; i++) {
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+",ok");
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            threadPool.shutdown();
        }
    }
}

在这里插入图片描述

四大拒绝策略
在这里插入图片描述> 小结和拓展
问题:最大线程到底如何定义

在这里插入图片描述在这里插入图片描述

13.四大函数式接口(必需掌握)

在这里插入图片描述在这里插入图片描述

13.1.四大函数式接口Function

在这里插入图片描述在这里插入图片描述

13.2.四大函数式接口Predicate

在这里插入图片描述在这里插入图片描述

13.3.四大函数式接口Consumer,消费型接口

在这里插入图片描述在这里插入图片描述

13.3.四大函数式接口Supplier,供给型接口

在这里插入图片描述在这里插入图片描述

14.Stream流式计算

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

15.ForkJoin

在这里插入图片描述

16.ForkJoin

在这里插入图片描述

ForkJoin

public class ForkJoinDemo extends RecursiveTask<Long> {
    private Long start;
    private Long end;

    private Long temp=10000L;

    public ForkJoinDemo(Long start, Long end) {
        this.start = start;
        this.end = end;
    }


    //计算方法
    @Override
    protected Long compute() {
        if((end-start)<temp){
            Long sum=0L;
            for (Long i = start; i <end ; i++) {
                sum+=i;
            }
           return sum;
        }else{ //forkjoin
            long middle=(start+end)/2;
            ForkJoinDemo task1 = new ForkJoinDemo(start, middle);
            task1.fork();
            ForkJoinDemo task2 = new ForkJoinDemo(middle+1, end);
            task2.fork();
            return task1.join()+task2.join();
        }
    }
}

测试代码

public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //test1();//时间:5289
        //test2();//时间:3533
        test3(); //时间:155
    }
    public static void test1(){
        Long sum=0L;
        long start=System.currentTimeMillis();
        for (Long i = 0L; i <=10_0000_0000 ; i++) {
            sum+=i;
        }
        long end=System.currentTimeMillis();
        System.out.println("sum="+sum+" 时间:"+(end-start));
    }
    //会使用ForkJoin
    public static void test2() throws ExecutionException, InterruptedException {
        long start=System.currentTimeMillis();
        
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        ForkJoinDemo task = new ForkJoinDemo(0L,10_0000_0000L);
        ForkJoinTask<Long> submit = forkJoinPool.submit(task);
        Long sum = submit.get();
        long end=System.currentTimeMillis();
        System.out.println("sum="+sum+" 时间:"+(end-start));
    }

    //会使用ForkJoin
    public static void test3() throws ExecutionException, InterruptedException {
        long start=System.currentTimeMillis();
        //Stream并行流
        long sum = LongStream.rangeClosed(0L, 10_0000_0000L).parallel().reduce(0, Long::sum);
        long end=System.currentTimeMillis();
        System.out.println("sum="+sum+" 时间:"+(end-start));
    }
}

在这里插入图片描述

16.异步回调
public class Demo01 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //发起一个请求
        //没有返回值的runAsync异步回调
      /*  CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "runAsync=>Void");
        });

        System.out.println("1111");

        completableFuture.get(); //获取阻塞执行的结果*/
        CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(()->{
            System.out.println(Thread.currentThread().getName() + "supplyAsync=>Integer");
            //int i=10/0;
            return 1024;
        });
        System.out.println(completableFuture.whenComplete((t, u) -> {
            System.out.println("t=>" + t);//正常的返回结果
            System.out.println("u=>" + u);//错误信息
        }).exceptionally((e) -> {
            System.out.println(e.getMessage());
            return 233;//可以获取到错误的返回结果
        }).get());
    }
}

在这里插入图片描述

16.JMM

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

public class JMMDemo {
    private volatile static int num=0;

    public static void main(String[] args) {

        new Thread(()->{
            while(num==0){

            }
        }).start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        num=1;
        System.out.println(num);
    }
}

在这里插入图片描述

public class VDemo02 {

    //volatile不保证原子性
    private volatile   static  int num=0;

    public  static void add(){
        num++;
    }
    public  static void main(String[] args) {

        for (int i = 1; i <=20; i++) {
            new Thread(()->{
                for (int j = 0; j < 1000; j++) {
                    add();
                }
            }).start();
        }

        while(Thread.activeCount()>2){//main jc
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName()+":"+num);
    }
}

在这里插入图片描述在这里插入图片描述

public class VDemo02 {

    //volatile不保证原子性
    //AtomicInteger 是一个原子性的integer
    private volatile   static AtomicInteger num=new AtomicInteger();

    public  static void add(){
        //num++; //不是一个原子性操作
        num.getAndIncrement();//AtomicInteger +1 方法 CAS
    }
    public  static void main(String[] args) {

        for (int i = 1; i <=20; i++) {
            new Thread(()->{
                for (int j = 0; j < 1000; j++) {
                    add();
                }
            }).start();
        }

        while(Thread.activeCount()>2){//main jc
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName()+":"+num);
    }
}

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

17.彻底玩转单例模式

在这里插入图片描述

饿汉式

public class Hungry {

    //可能会浪费空间
    private byte[] data1=new byte[1024*1024];
    private byte[] data2=new byte[1024*1024];
    private byte[] data3=new byte[1024*1024];
    private byte[] data4=new byte[1024*1024];

    private Hungry(){

    }

    private final static Hungry HUNGRY=new Hungry();

    public static Hungry getInstance(){
        return HUNGRY;
    }
}

//懒汉式单例
public class LazyMan {
    private LazyMan(){
        synchronized (LazyMan.class){
            if(lazyMan!=null){
                throw new RuntimeException("不要试图使用反射破坏异常");
            }
        }
        System.out.println(Thread.currentThread().getName()+"ok");
    }

    private volatile static LazyMan lazyMan;

    //双重检测锁模式的 懒汉式单例 DCL懒汉式
    private static LazyMan getInstance(){
        if(lazyMan==null) {
            synchronized (LazyMan.class) {
                if (lazyMan == null) {
                    lazyMan = new LazyMan();
                }
            }
        }
        return lazyMan;
    }


    //反射
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        LazyMan instance = LazyMan.getInstance();
        Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
        declaredConstructor.setAccessible(true);

        //LazyMan instance = declaredConstructor.newInstance();
        LazyMan instance2 = declaredConstructor.newInstance();

        System.out.println(instance);
        System.out.println(instance2);
    }


}

在这里插入图片描述

静态内部类
在这里插入图片描述

在这里插入代码片

单例不安全,反射
枚举
如果两个都是通过反射来创建的
反编译.class文件命令
在这里插入图片描述
使用jad,把我们的源码变成.java文件
在这里插入图片描述

//enum 是一个什么?本身是一个Class类
public enum EnumSingle{

        INSTANCE;

    public EnumSingle getInstance(){
        return INSTANCE;
    }
}
class Test{

    //反射
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //LazyMan instance = LazyMan.getInstance();
        EnumSingle instance1=EnumSingle.INSTANCE;
        Constructor<EnumSingle> declaredConstructor = EnumSingle.class.getDeclaredConstructor(String.class,int.class);
        declaredConstructor.setAccessible(true);
        EnumSingle instance2 = declaredConstructor.newInstance();

        System.out.println(instance1);
        System.out.println(instance2);
    }


}

在这里插入图片描述

18.深入理解CAS

在这里插入图片描述在这里插入图片描述

ABA问题


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

        //CAS compareAndSet:比较并交换
        // 期望,更新
        // 如果我期望的值达到了,那么就更新,否则,就不更新,CAS是CPU的并发原语
        AtomicInteger atomicInteger = new AtomicInteger(2020);

        //=======================捣乱的线程============================
        System.out.println(atomicInteger.compareAndSet(2020, 2021));
        System.out.println(atomicInteger.get());

        System.out.println(atomicInteger.compareAndSet(2021, 2020));
        System.out.println(atomicInteger.get());

        //======================期望的线程============================
        System.out.println(atomicInteger.compareAndSet(2020, 6666));
        System.out.println(atomicInteger.get());
    }
}

19.原子引用

在这里插入图片描述

在这里插入图片描述

public class CASDemo {

    //CAS compareAndSet:比较并交换
    // 期望,更新
    // 如果我期望的值达到了,那么就更新,否则,就不更新,CAS是CPU的并发原语
    //AtomicStampedReference 注意,如果泛型是一个包装类,注意对象的引用问题

    //正常在业务操作,这里面比较的都是一个个对象
    static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(1,1);

    public static void main(String[] args) {



        new Thread(()->{
            int stamp = atomicStampedReference.getStamp();//获得版本号
            System.out.println("a1=>"+stamp);

            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(atomicStampedReference.compareAndSet(1, 2,
                    atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1));
            System.out.println("a2=>"+atomicStampedReference.getStamp());

            System.out.println(atomicStampedReference.compareAndSet(2, 1,
                    atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1));
            System.out.println("a3=>"+atomicStampedReference.getStamp());
        },"a").start();

        new Thread(()->{
            int stamp = atomicStampedReference.getStamp();//获得版本号
            System.out.println("b1=>"+stamp);

            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(atomicStampedReference.compareAndSet(1, 6,
                    stamp, stamp + 1));

            System.out.println("b2=>"+atomicStampedReference.getStamp());

        },"b").start();


    }
}

在这里插入图片描述

20.各种锁的理解
20.1.公平锁,非公平锁

在这里插入图片描述

20.2.可重入锁

在这里插入图片描述

synchronized版

// synchronized
public class Demo01 {
    public static void main(String[] args) {
        Phone phone = new Phone();

        new Thread(()->{
            phone.sms();
        },"A").start();

        new Thread(()->{
            phone.sms();
        },"B").start();

    }
}


class Phone{

    public synchronized void sms(){
        System.out.println(Thread.currentThread().getName()+":sms");
        call(); //这里也有锁
    }

    public synchronized void call() {
        System.out.println(Thread.currentThread().getName()+":call");
    }
}

在这里插入图片描述

lock版

// Lock
public class Demo02 {
    public static void main(String[] args) {
        Phone2 phone = new Phone2();

        new Thread(()->{
            phone.sms();
        },"A").start();

        new Thread(()->{
            phone.sms();
        },"B").start();

    }
}


class Phone2{

    Lock lock=new ReentrantLock();

    public  void sms(){
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName()+":sms");
            call(); //这里也有锁
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public  void call() {

        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName()+":call");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

在这里插入图片描述

20.3.自旋锁

在这里插入图片描述我们来自定义一个锁来测试

public class SpinlockDemo {
    //int 0
    //Thread null
    AtomicReference<Thread> atomicReference= new AtomicReference<>();

    //加锁
    public void myLock(){
        Thread thread = Thread.currentThread();
        System.out.println(Thread.currentThread().getName()+"==> mylock");

        //自旋锁
        while(!atomicReference.compareAndSet(null,thread)){

        }
    }
    //解锁
    public void myUnLock(){
        Thread thread = Thread.currentThread();
        System.out.println(Thread.currentThread().getName()+"==> myUnlock");
        atomicReference.compareAndSet(thread,null);
    }

}

测试类:

public class TestSpinlock {
    public static void main(String[] args) throws InterruptedException {
        SpinlockDemo lock = new SpinlockDemo();

        new Thread(()->{
            lock.myLock();
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                lock.myUnLock();
            }
        },"T1").start();

        TimeUnit.SECONDS.sleep(1);

        new Thread(()->{
            lock.myLock();
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                lock.myUnLock();
            }
        },"T2").start();


    }
}

在这里插入图片描述

20.4.死锁

死锁是什么
在这里插入图片描述> 死锁测试,怎么去分析死锁

public class DeadLockDemo {
    public static void main(String[] args) {
        String lockA="lockA";
        String lockB="lockB";

        new Thread(new MyThread(lockA,lockB),"T1").start();
        new Thread(new MyThread(lockB,lockA),"T2").start();

    }
}

class MyThread implements Runnable{

    private String lockA;
    private String lockB;

    public MyThread(String lockA, String lockB) {
        this.lockA = lockA;
        this.lockB = lockB;
    }

    @Override
    public void run() {
        synchronized (lockA){
            System.out.println(Thread.currentThread().getName()+"lock"+lockA+"=>get"+lockB);

            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lockB) {
                System.out.println(Thread.currentThread().getName()+"lock"+lockB+"=>get"+lockA);
            }
        }
    }
}

在这里插入图片描述在这里插入图片描述在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值