并发编程学习笔记

Runnable 没有返回值 效率相比 Callable 较低
查看Thread.start源码可知Java自己无法直接开启线程,而是调用本地方法 private native void start0(); 也就是底层C++类库的方法,Java本身无法直接操作硬件
获取CPU核数

Runtime.getRuntime().availableProcessors()

线程的六种状态
    public enum State {
        /**
         * 新生
         */
        NEW,

        /**
		 * 运行
         */
        RUNNABLE,

        /**
         * 阻塞
         */
        BLOCKED,

        /**
         * 等待(不会超时的等待)
         */
        WAITING,

        /**
         * 超时等待(会超时的等待)
         */
        TIMED_WAITING,

        /**
         * 终止
         */
        TERMINATED;
    }
wait 和 sleep 的区别
1) 来自不同的类
wait -> Object
sleep -> Thread
2) 锁的释放
wait释放锁,sleep不释放锁
3)使用范围
wait 只能在同步代码块中使用,否则会抛出java.lang.IllegalMonitorStateException 程序中断异常
sleep随时随地都可以用

Lock

ReentrantLock 默认是NonfairSync非公平锁可以插队,FairSync按先来后到顺序不可插队
    public ReentrantLock() {
        sync = new NonfairSync();
    }

    /**
     * Creates an instance of {@code ReentrantLock} with the
     * given fairness policy.
     *
     * @param fair {@code true} if this lock should use a fair ordering policy
     */
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

synchronized 和Lock的区别
1、Synchronized内置的Java关键字,Lock是一个Java类
2、Synchronized 无法判断获取锁的状态,Lock 可以判断是否获取到了锁
3、Synchronized 会自动释放锁,lock必须要手动释放锁!如果不释放锁,死锁
4、Synchronized 线程1(获得锁,阻塞)、线程2(等待,傻傻的等) ;Lock锁就不一定会等待下去;
5、Synchronized 可重入锁,不可以中断的,非公平;Lock,可重入锁,可以判断锁,非公平(可以自己设置);
6、Synchronized适合锁少量的代码同步问题,Lock适合锁大量的同步代码!

当线程大于两个时便可能存在虚假唤醒的情况:因为使用的是if,执行完if内的内容唤醒后便会继续执行后续代码而不会再次判断等待条件, 换句话说,等待应该总是出现在循环中的
public class PC {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.decrement();
            }
        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.increment();
            }
        },"B").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.decrement();
            }
        },"C").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.increment();
            }
        },"D").start();
    }
}

class Data {
    private int number = 0;

    public synchronized void increment() {
        if (number > 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        number++;
        System.out.println(Thread.currentThread().getName() + "=>" + number);
        this.notifyAll();
    }

    public synchronized void decrement() {
        if (number <= 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        number--;
        System.out.println(Thread.currentThread().getName() + "=>" + number);
        this.notifyAll();
    }
}

public class PC {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.decrement();
            }
        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.increment();
            }
        },"B").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.decrement();
            }
        },"C").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.increment();
            }
        },"D").start();
    }
}

class Data {
    private int number = 0;

    public synchronized void increment() {
        while (number > 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        number++;
        System.out.println(Thread.currentThread().getName() + "=>" + number);
        this.notifyAll();
    }

    public synchronized void decrement() {
        while (number <= 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        number--;
        System.out.println(Thread.currentThread().getName() + "=>" + number);
        this.notifyAll();
    }
}

通过JUC实现的生产者消费者 ReentrantLock 和 Condition
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class PC {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.decrement();
            }
        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.increment();
            }
        },"B").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.decrement();
            }
        },"C").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.increment();
            }
        },"D").start();
    }
}

class Data {
    private int number = 0;

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

    public void increment() {
        lock.lock();
        try {
            while (number > 0) {
                try {
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            number++;
            System.out.println(Thread.currentThread().getName() + "=>" + number);
            condition.signalAll();
        } finally {
            lock.unlock();
        }



    }

    public void decrement() {
        lock.lock();
        try {
            while (number <= 0) {
                try {
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            number--;
            System.out.println(Thread.currentThread().getName() + "=>" + number);
            condition.signalAll();
        } finally {
            lock.unlock();
        }

    }
}

Condition 的优势 精准的通知 唤醒线程

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionTest {
    public static void main(String[] args) {
        ConditionTest01 conditionTest01 = new ConditionTest01();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                conditionTest01.method01();
            }
        },"AAAA").start();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                conditionTest01.method02();
            }
        },"BBBB").start();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                conditionTest01.method03();
            }
        },"CCCC").start();
    }
}

class ConditionTest01  {
    Lock lock = new ReentrantLock();
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    Condition condition3 = lock.newCondition();

    private int number = 2;
    public void method01() {
        lock.lock();
        try {
// 这里为了测试是否真的精准唤醒不会虚假唤醒而使用if  实际使用上就应该按上文说的用while
            if (number != 1){
                try {
                    condition1.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            number = 2;
            System.out.println(Thread.currentThread().getName()+"唤醒了condition2");
            condition2.signal();
        } finally {
            lock.unlock();
        }

    }

    public void method02() {
        lock.lock();
        try {
            if (number != 2){
                condition2.await();
            }
            number = 3;
            System.out.println(Thread.currentThread().getName()+"唤醒了condition3");
            condition3.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }

    public void method03() {
        lock.lock();
        try {
            if (number != 3){
                condition3.await();
            }
            number = 1;
            System.out.println(Thread.currentThread().getName()+"唤醒了condition1");
            condition1.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

8锁现象

1)标准情况下,一个对象 两个同步方法 第一个线程先拿到锁 谁先执行
2)一个对象 两个同步方法 第一个线程先拿到锁 第一个方法延迟4S 谁先执行
3)一个对象 一个同步方法一个普通方法 第一个线程先拿到锁 谁先执行
4)两个对象 两个同步方法 第一个线程先拿到锁 第一个方法延迟4S 谁先执行
5)一个对象 两个静态同步方法 第一个线程先拿到锁 第一个方法延迟4S 谁先执行
6)两个对象 两个静态同步方法 第一个线程先拿到锁 第一个方法延迟4S 谁先执行
7)一个对象 一个静态同步方法一个普通同步方法 第一个线程先拿到锁 第一个方法延迟4S 谁先执行
8)两个个对象 一个静态同步方法一个普通同步方法 第一个线程先拿到锁 第一个方法延迟4S 谁先执行
package com.ambition;

import java.util.concurrent.TimeUnit;

/**
 * 同一个对象  两个线程  两个同步方法 谁先执行?
 **/

public class Question1 {


    public static void main(String[] args) {
        Phone phone = new Phone();
        new Thread(() -> phone.sendMsg()).start();
//        延迟的目的是控制哪个线程先拿到锁
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(() -> phone.call()).start();
    }
}

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

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

小结
new this 锁的具体的对象
static 锁的是 Class 全局唯一的模板

集合类不安全

1. List 不安全
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

public class ListTest {
//    java.util.ConcurrentModificationException 并发修改异常
    public static void main(String[] args) {
        /*
        * 解决方案
        * 1.List<String> list = new Vector<>();
        * 2.List<String> list = Collections.synchronizedList(new ArrayList<>());
        * 3.List<String> list = new CopyOnWriteArrayList<>();
        * COW 读写分离 在写入的时候复制一份再编辑 再塞回去
        * */
        List<String> list = new CopyOnWriteArrayList<>();
        for (int i = 1; i <= 10; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(0, 5));
                System.out.println(list);
            }, String.valueOf(i)).start();

        }
    }
}

2. Set 不安全
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;

public class SetTest {
    public static void main(String[] args) {
//        Set set = new HashSet();
//        Set set = Collections.synchronizedSet(new HashSet());
        Set set = new CopyOnWriteArraySet();
        for (int i = 1; i <= 20; i++) {
            new Thread(() ->{
                set.add(UUID.randomUUID().toString().substring(0, 5));
                System.out.println(set);
            },String.valueOf(i)).start();
        }
    }
}

HashSet 的本质
// 就是一个map
    public HashSet() {
        map = new HashMap<>();
    }


    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
3.Map不安全
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

public class MapTest {
    public static void main(String[] args) {
//        Map<String, String> map = new HashMap<>();
//        Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
        Map<String, String> map = new ConcurrentHashMap<>();
        for (int i = 1; i <= 20; i++) {
            new Thread(() -> {
                map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 5));
                System.out.println(map);
            },String.valueOf(i)).start();
        }
    }
}

Callable和Thread结合

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CallTest {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        FutureTask<Integer> futureTask = new FutureTask(myThread);
        new Thread(futureTask).start();
        new Thread(futureTask,"B").start();//就算新建两个线程也只会执行一次 执行结果会被缓存
        try {
            Integer result = futureTask.get();//如果是耗时操作 可能会阻塞 因为获取结果需要等待
            System.out.println(result);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

class MyThread implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        System.out.println("call……");
        return 1024;
    }
}

常用辅助类

1.CountDownLatch 减法计数器
import java.util.concurrent.CountDownLatch;

public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 1; i <= 6; i++) {
            new Thread(()-> {
                System.out.println(Thread.currentThread().getName() + "Go out");
//                计数器-1
                countDownLatch.countDown();
            },String.valueOf(i)).start();
        }
//        等到计数器归零 才继续往下执行
        countDownLatch.await();
        System.out.println("Close door");
    }
}

2.CyclicBarrier
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7,() -> System.out.println("召唤神龙!!!!!!!"));
        for (int i = 1; i <= 7; i++) {
            final int temp = i;
            new Thread(() -> {
                System.out.println("收集到了第"+ temp + "颗龙珠!");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

3.Semaphore
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaphoreDemo {
    public static void main(String[] args) {
//        作用:多个共享资源的互斥使用  高并发下限流
        Semaphore semaphore = new Semaphore(3);
        for (int i = 1; i <= 6; i++) {
            new Thread(()-> {
                try {
//                    获取信号量,如果信号量满了线程等待
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+ "抢到了车位");
                    TimeUnit.SECONDS.sleep(3);
                    System.out.println(Thread.currentThread().getName()+ "离开了车位");
//                    释放当前信号量 唤醒等待的线程
                    semaphore.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}

读写锁

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockDemo {

    public static void main(String[] args) {
        MyCache myCache = new MyCache();
        for (int i = 1; i <= 5; i++) {
            new Thread(() -> {
                myCache.put(Thread.currentThread().getName(),"Hello World");
            },String.valueOf(i)).start();
        }

        for (int i = 1; i <= 5; i++) {
            new Thread(() -> {
                myCache.get(Thread.currentThread().getName());
            },String.valueOf(i)).start();
        }
    }
}

class MyCache {
    private Map<String,String> map = new HashMap<>();
    ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    public void put(String key, String value) {
//        写锁(独占锁) 一次只能被一个线程占有
        readWriteLock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+ "写入");
            map.put(key,value);
            System.out.println(Thread.currentThread().getName()+ "写入成功");
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }

    public void get(String key) {
        try {
//            读锁(共享锁) 可以同时被多个线程占有
            readWriteLock.readLock().lock();
            System.out.println(Thread.currentThread().getName()+ "读取");
            map.get(key);
            System.out.println(Thread.currentThread().getName()+ "读取成功");
        } finally {
            readWriteLock.readLock().unlock();
        }

    }
}

阻塞队列

1.BlockingQueue
方式抛出异常有返回值不抛异常阻塞等待超时等待
添加addoffer()putoffer(E e, long timeout, TimeUnit unit)
移除removepoll()takepoll(long timeout, TimeUnit unit)
判断队列首elementpeek--
package com.ambition.queen;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * @program: springboot-08-shiro
 * @description:
 * @author: zhengzx
 * @create: 2022-03-08 15:54
 **/

public class BlockingQueueDemo {

    public static void main(String[] args) {

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

    }

    /**
     * 抛出异常
     */
    public static void test01() {
        ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(3);
        System.out.println(queue.add(1));
        System.out.println(queue.add(2));
        System.out.println(queue.add(3));

        System.out.println("========");
        System.out.println(queue.remove());
        System.out.println(queue.remove());
        System.out.println(queue.remove());
        System.out.println(queue.element());
        System.out.println(queue.remove());
    }

    /**
     * 有返回值,不抛出异常
     */
    public static void test02() {
        ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(3);
        System.out.println(queue.offer(1));
        System.out.println(queue.offer(2));
        System.out.println(queue.offer(3));
        System.out.println(queue.offer(4));
        System.out.println("========");
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.peek());

        System.out.println(queue.poll());
    }

    /**
     * 等待,一直阻塞
     * @throws InterruptedException
     */
    public static void test03() throws InterruptedException {
        ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(3);
        queue.put(1);
        queue.put(2);
        queue.put(3);
//        queue.put(4);
        System.out.println(queue.take());
        System.out.println(queue.take());
        System.out.println(queue.take());
        System.out.println(queue.take());
    }


    /**
     * 超时等待
     */
    public static void test04() throws InterruptedException {
        ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(3);
        System.out.println(queue.offer(1));
        System.out.println(queue.offer(2));
        System.out.println(queue.offer(3));
        System.out.println(queue.offer(4,2, TimeUnit.SECONDS));
        System.out.println("========");
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll(2, TimeUnit.SECONDS));
    }
}

2.SynchronizedPriorityQueue 同步队列 没有容量 进去一个元素必须等这个元素取出来之后才能放下一个元素
package com.ambition.queen;

import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

/**
 * @program: springboot-08-shiro
 * @description:
 * @author: zhengzx
 * @create: 2022-03-08 16:45
 **/

public class SynchronousQueueDemo {
    public static void main(String[] args) {
        SynchronousQueue<String> queue = new SynchronousQueue();
        new Thread(() -> {
            try {
                System.out.println(Thread.currentThread().getName() + " PUT A");
                queue.put("A");
                System.out.println(Thread.currentThread().getName() + " PUT B");
                queue.put("B");
                System.out.println(Thread.currentThread().getName() + " PUT C");
                queue.put("C");

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"T1").start();

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

线程池

1.三大方法
package com.ambition.pool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @program: springboot-08-shiro
 * @description:
 * @author: zhengzx
 * @create: 2022-03-08 17:47
 **/

public class Demo1 {
    public static void main(String[] args) {
//        ExecutorService threadPool = Executors.newSingleThreadExecutor();//单个线程
//        ExecutorService threadPool = Executors.newFixedThreadPool(3);//固定大小的线程池
        ExecutorService threadPool = Executors.newCachedThreadPool();//可伸缩的线程池
        try {
            for (int i = 0; i < 10; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "OK");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
}

2.七大参数
   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.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }
4. 【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样
的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明:Executors 返回的线程池对象的弊端如下: 1)FixedThreadPool 和 SingleThreadPool:
允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。 2)CachedThreadPool 和 ScheduledThreadPool:
允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。
手动创建一个线程池
        ExecutorService threadPool = new ThreadPoolExecutor(2, 5,
                3L, TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());//等待队列满后的拒绝策略
四种拒绝策略
/**
 * new ThreadPoolExecutor.AbortPolicy() 满员后直接抛出异常
 * new ThreadPoolExecutor.CallerRunsPolicy() 满员后 新来的哪个线程发起的 就丢回去让哪个线程执行
 * new ThreadPoolExecutor.DiscardPolicy() 满员后直接丢掉新来的 不抛出异常
 * new ThreadPoolExecutor.DiscardOldestPolicy() 满员后尝试与更早的线程竞争 竞争失败也不抛出异常
 **/
线程池大小定义策略
1)CPU密集型:CPU几核最大线程数就定义几
2)IO密集型:根据程序中有多少个非常费IO的任务 去定义,一般为两倍

四大函数式接口

函数式接口:只有一个方法的接口

1.public interface Function<T, R>
import java.util.function.Function;

public class FunctionTest {
    public static void main(String[] args) {
        Function<String, String> function = new Function<String, String>() {
            /**
             * Applies this function to the given argument.
             *
             * @param s the function argument
             * @return the function result
             */
            @Override
            public String apply(String s) {
                return s+":hhhh";
            }
        };
        System.out.println(function.apply("123"));

        Function<String, String> function2 = (a) ->{ return a + ":hhhh";};
        System.out.println(function2.apply("456"));
    }
}

2.public interface Predicate
import java.util.function.Predicate;

public class PredicateTest {
    public static void main(String[] args) {
//        断定型接口 有一个入参,返回值只能是布尔值
        Predicate<String> predicate = new Predicate<String>() {
            /**
             * Evaluates this predicate on the given argument.
             *
             * @param s the input argument
             * @return {@code true} if the input argument matches the predicate,
             * otherwise {@code false}
             */
            @Override
            public boolean test(String s) {
                return s != null && s.equals("HELLO");
            }
        };
        System.out.println(predicate.test("WORLD"));


        Predicate<String> predicate2 = a ->  a != null && a.equals("HELLO");
        System.out.println(predicate2.test("HELLO"));
    }
}

3.public interface Consumer
import java.util.function.Consumer;

public class ConsumerTest {
    public static void main(String[] args) {
//        消费型接口 只有输入没有返回
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        consumer.accept("Hello");
        Consumer<String> consumer2 = System.out::print;
        consumer2.accept("World");
    }
}

4.public interface Supplier
import java.util.function.Supplier;
public class SupplierTest {
    public static void main(String[] args) {
//        供给型接口  只返回 不输入
        Supplier<Integer> supplier = new Supplier<Integer>() {
            @Override
            public Integer get() {
                System.out.println("get");
                return 1025;
            }
        };
        System.out.println(supplier.get());

        Supplier<Integer> supplier2 = () -> {
            System.out.println("get");
            return 1024;
        };
        System.out.println(supplier2.get());
    }
}

ForkJoin

起始于jdk1.7 用于并行执行任务

package com.ambition.forkjoin;

import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

public class ForkJoinDemo extends RecursiveTask<Long> {
    private Long start;
    private Long end;
    private static final Long MAX_NUMBER = 100000L;

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

    /**
     * The main computation performed by this task.
     *
     * @return the result of the computation
     */
    @Override
    protected Long compute() {
        Long result = 0L;
        if ((end - start) < MAX_NUMBER) {
            for (Long i = start;i <= end;i++) {
                result += i;
            }
            return result;
        } else {
            long mid = (start + end) / 2;
            ForkJoinDemo task1 = new ForkJoinDemo(start, mid);
            ForkJoinTask<Long> result1 = task1.fork();
            ForkJoinDemo task2 = new ForkJoinDemo(mid + 1, end);
            ForkJoinTask<Long> result2 = task2.fork();
            return result1.join() + result2.join();
        }

    }
}







package com.ambition.forkjoin;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;

public class ForkJoinTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
//        test01();//7470
//        test02();//3966
        test03();//164
    }

    public static void test01() {
        long start = System.currentTimeMillis();
        Long sum = 0L;
        for (Long i = 0L; i < 10_0000_0000;i++) {
            sum += i;
        }
        long end = System.currentTimeMillis();
        System.out.println("sum=" + sum + ",cost:" + (end - start));
    }

    public static void test02() throws ExecutionException, InterruptedException {
        long start = System.currentTimeMillis();

        ForkJoinDemo forkJoinDemo = new ForkJoinDemo(0L,10_0000_0000L);
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        ForkJoinTask<Long> submit = forkJoinPool.submit(forkJoinDemo);
        Long sum = submit.join();

        long end = System.currentTimeMillis();
        System.out.println("sum=" + sum + ",cost:" + (end - start));
    }


    public static void test03() throws ExecutionException, InterruptedException {
        long start = System.currentTimeMillis();

        long sum = LongStream.rangeClosed(0L, 10_0000_0000L).parallel().reduce(0L, Long::sum);

        long end = System.currentTimeMillis();
        System.out.println("sum=" + sum + ",cost:" + (end - start));
    }
}

异步回调

package com.ambition.future;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * 子线程是异步执行的,主线程休眠等待子线程执行完成,子线程执行完成后唤醒主线程,主线程获取任务执行结果后退出。
 **/

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

        System.out.println("=======");
        completableFuture.join();
        System.out.println("||||||");*/
//        有返回值的异步回调
        CompletableFuture<Integer> cf1 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "=>supplyAsync1111");

            return 1024;
        });
        CompletableFuture<Integer> cf2 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "=>supplyAsync2222");

            return 2048;
        });
//        cf1 和 cf2 都执行完后执行给定任务 cf1 cf2的执行结果作为入参
/*        CompletableFuture<Integer> cf3 = cf1.thenCombine(cf2, (a, b) -> {
            System.out.println("a=>" + a);
            System.out.println("b=>" + b);
            return a + b;
        });*/

//        回调执行结果 t相当于 success  u相当于error
        cf2.whenComplete((t,u)-> {
            System.out.println("t=>"+t);
            System.out.println("u=>"+u);
        }).exceptionally((e)-> {
            System.out.println(e.getMessage());
            return 404;
        });
        cf1.whenComplete((t,u)-> {
            System.out.println("t=>"+t);
            System.out.println("u=>"+u);
        }).exceptionally((e)-> {
            System.out.println(e.getMessage());
            return 404;
        });

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值