JAVA JUC学习记录

线程和进程

进程:一个程序、QQ.exe程序的集合
一个进程通常包含多个线程

线程有几个状态
  • New 新生
  • RUNNABLE 运行
  • BLOCKED 阻塞
  • WAITTING 等待
  • TIMED_WAITTING 超时等待
  • TERMINATED 终止
wait/sleep的区别

1、来自不同的类

wait => Object
sleep => Thread

2、关于锁的释放

wait 会释放锁,sleep 不会释放锁

3、使用范围是不同的

wait必须在同步代码块中
sleep可以在任何地方使用

4、是否需要捕获异常

wait不需要捕获异常
sleep需要捕获异常

Lock锁 和Synchronized
  1. Synchronized 是一个内置的关键字,Lock是一个Java类
  2. Synchonized无法获取锁的状态,Lock锁是可以获取锁的状态
  3. Synchonized 会自动施法锁,Lock需要手动释放锁,不释放会死锁
  4. Synchonized 会产生阻塞;Lock锁不会一直等待
  5. Synchonized 可重入锁,不可以中断,非公平的;Lock 可重入锁。可以判断锁。默认非公平的(可以自己设置)
  6. Synchonized 适合锁少量的同步代码,Lock锁适合锁大量的同步代码

锁是什么?如果判断锁是谁?

第一种情况:一个对象,两个synchronized方法,锁的是对象,因为用了同一个对象,所以用的是用一把锁,谁先拿到锁,就谁先执行
输出:
sendSms
call

package juc;

import java.util.concurrent.TimeUnit;

public class lock8 {
    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("sendSms");
    }
    public synchronized  void call(){
        System.out.println("call");
    }
}

在这里插入图片描述

**第二种情况:**两个不同的对象,两个synchronized 方法,因为是两个对象,synchronized 锁的是不同的对象,所以没有公用一把锁。因此先输出call后输出sendsms

package juc;

import java.util.concurrent.TimeUnit;

public class lock8 {
    public static void main(String[] args) {
        Phone phone = new Phone();
        Phone phone1 = new Phone();
        new Thread(()->{
            phone.sendSms();
        },"A").start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(()->{
            phone1.call();
        },"B").start();

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

在这里插入图片描述

**第三种情况:**同一个对象,一个synchronized同步方法,和一个普通方法,由于一个是普通方法,根本没上锁,所以锁只是锁了sendSms,所以会先执行hello,sendSms sleep了时间

package juc;

import java.util.concurrent.TimeUnit;

public class lock8 {
    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.hello();
        },"B").start();

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

在这里插入图片描述

**第四种情况:**两个静态的同步方法,一个对象,静态的同步方法,锁的是class模板,所以用的是同一个锁,谁先拿到锁谁先输出

package juc;

import java.util.concurrent.TimeUnit;

public class LockStatic {

        public static void main(String[] args) {
            Phone2 phone2=new Phone2();
//            Phone2 phone21=new Phone2();
            new Thread(()->{
                phone2.sendSms();
            },"A").start();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            new Thread(()->{
                phone2.call();
            },"B").start();
//            new Thread(()->{
//                phone2.hello();
//            },"C").start();
        }
    }
    class Phone2{
        //    synchronized 锁的对象是方法的调用者
//    两个方法用的是同一个锁,谁先拿到谁先执行
        public  static synchronized  void sendSms(){
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sendSms");
        }
        public  static  synchronized  void call(){
            System.out.println("call");
        }
        public  void  hello(){
            System.out.println("hello");
        }

}

在这里插入图片描述

第五种情况:一个静态的同步方法,一个普通的同步方法,两个对象
因为静态同步方法锁的是class模板 ,而普通的同步方法锁的是对象,因此锁的是不同的,所以会先输出call

package juc;

import java.util.concurrent.TimeUnit;

public class LockStatic {

        public static void main(String[] args) {
            Phone2 phone2=new Phone2();
            Phone2 phone21=new Phone2();
            new Thread(()->{
                phone2.sendSms();
            },"A").start();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            new Thread(()->{
                phone21.call();
            },"B").start();
//            new Thread(()->{
//                phone2.hello();
//            },"C").start();
        }
    }
    class Phone2{
        //    synchronized 锁的对象是方法的调用者
//    两个方法用的是同一个锁,谁先拿到谁先执行
        public  static synchronized  void sendSms(){
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sendSms");
        }
        public    synchronized  void call(){
            System.out.println("call");
        }
        public  void  hello(){
            System.out.println("hello");
        }

}

在这里插入图片描述

集合类不安全

ArrayList 是线程不安全的
解决方案1:把ArrayList改成线程安全的 Collections.synchronizedList
解决方案2: 使用CopyOnWriteArrayList线程安全

package juc;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

public class Test04 {
     public static void main(String[] args) {
//          线程不安全的
//          解决方案1  List<String> arrayList = Collections.synchronizedList(new ArrayList<>()); 把arraylist搞成线程安全的
//             解決方案2 :List<String> arrayList =new CopyOnWriteArrayList<>();
//               List<String> arrayList = Collections.synchronizedList(new ArrayList<>());
	     List<String> arrayList =new CopyOnWriteArrayList<>();
//          ConcurrentModificationException   并发修改异常,在多线程的条件下,ArrayList是线程不安全的
        //  List<String> arrayList =new ArrayList<>() ;
          for (int i = 0; i <30 ; i++) {
               new Thread(()->{
                    arrayList.add(UUID.randomUUID().toString().substring(0,5));
                    System.out.println(arrayList);
               },String.valueOf(i)).start();
          }
     }
}

HashSet

和List是同样的解决方案

解决方案1:把HashSet改成线程安全的 Collections.synchronizedList
解决方案2: 使用CopyOnWriteArraySet线程安全

Map

Map不安全的,
使用ConcurrentHashMap线程安全的

package juc;

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) {
//        会产生ConcurrentModificationException 并发修改异常
//        Map<String,String> hashMap = new HashMap<>();
        ConcurrentHashMap<String,String> hashMap = new ConcurrentHashMap<>();
        for (int i = 1; i <50 ; i++) {
            new Thread(()->{
                hashMap.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,5));
                System.out.println(hashMap);
            },String.valueOf(i)).start();
        }
    }
}

常用的辅助类

countDownLatch(减法计数器)
package juc;

import java.util.concurrent.CountDownLatch;

public class countDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
//        总是是6,必须要执行任务的时候,在使用
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 1; i <=6 ; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"GO");
                countDownLatch.countDown(); //数量减1
            },String.valueOf(i)).start();
        }
        countDownLatch.await(); //等待计数器归0
        System.out.println("close");
    }
}

原理:countDownLatch.countDown() countDownLatch.await();

cyclicBarrier(加法计数器)
package juc;

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(Thread.currentThread().getName()+"拿了"+temp+"个");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}

原理: cyclicBarrier.await();

Semaphore(做限流比较多)
package juc;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class SemaphoreDemo {
    public static void main(String[] args) {
//        线程数量
        Semaphore semaphoreDemo = new Semaphore(3);
        for (int i = 1; i <= 6; i++) {
            new Thread(()->{
                try {
                    semaphoreDemo.acquire();
                    System.out.println(Thread.currentThread().getName()+"抢到车位");
                    TimeUnit.SECONDS.sleep(2);
                    System.out.println(Thread.currentThread().getName()+"离开车位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphoreDemo.release();
                }
            },String.valueOf(i)).start();
        }
    }
}

原理: semaphoreDemo.acquire(); 得到锁 semaphoreDemo.release(); 释放锁

ReadWriteLock
package juc;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/***
独占锁(写锁) 一次只能被一个线程占有
共享锁(读锁) 多个线程可以同时占有
读-读    可以共存
写-写  不可以共存
读-写  不可以共存
***/
public class ReentrantReadWriteLockDemo {
    public static void main(String[] args) {
        MyCacheLock myCache = new MyCacheLock();
//        MyCache myCache2 = new MyCache();
        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 lock=new ReentrantReadWriteLock();
    //存
    public  void  put(String key,Object value){
        lock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"写入"+key);
            map.put(key,value);
            System.out.println(Thread.currentThread().getName()+"写入完毕");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.writeLock().unlock();
        }

    }
    //取
    public  void get(String key){
        lock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"读取"+key);
            map.get(key);
            System.out.println(Thread.currentThread().getName()+"读取OK");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.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()+"写入完毕");
    }
    //取
    public  void get(String key){
        System.out.println(Thread.currentThread().getName()+"读取"+key);
        map.get(key);
        System.out.println(Thread.currentThread().getName()+"读取OK");
    }
}
阻塞队列 BlockingQueue

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

使用队列

方式抛出异常不抛出异常阻塞等待超时等待
添加addofferputoffer(value, 超时时间,超时时间单位)
删除removepolltakepoll(超时时间,超时时间单位)
package juc;

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

public class BlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        test3();
    }
    /**
     * 抛出异常
     */
    public  static  void  test1(){
        ArrayBlockingQueue blockingQueue =new ArrayBlockingQueue<>(3);
        blockingQueue.add("a");
        blockingQueue.add("b");
        blockingQueue.add("c");
        //.IllegalStateException: Queue full   抛出异常
//        System.out.println(blockingQueue.add("d"));
        blockingQueue.remove();
        blockingQueue.remove();
        blockingQueue.remove();
//        NoSuchElementException
//        System.out.println(blockingQueue.remove());
    }
    /**
     * 有返回值,不抛出异常
     */
    public  static  void test2(){
        ArrayBlockingQueue arrayBlockingQueue=new ArrayBlockingQueue<>(3);
//        往队列中加值
        arrayBlockingQueue.offer("a");
        arrayBlockingQueue.offer("a");
        arrayBlockingQueue.offer("a");
//        不抛出异常  返回 false
        System.out.println(arrayBlockingQueue.offer("a"));
//        往队列中去拿值
        arrayBlockingQueue.poll();
        arrayBlockingQueue.poll();
        arrayBlockingQueue.poll();
//        不抛出异常 返回null
        System.out.println(arrayBlockingQueue.poll());
    }
    /**
     * 阻塞等待
     */
    public  static  void  test3() throws InterruptedException {
        ArrayBlockingQueue arrayBlockingQueue=new ArrayBlockingQueue<>(3);
        arrayBlockingQueue.put("a");
        arrayBlockingQueue.put("a");
        arrayBlockingQueue.put("a");
//        arrayBlockingQueue.put("a"); //会一直死死的等待
        arrayBlockingQueue.take();
        arrayBlockingQueue.take();
        arrayBlockingQueue.take();
//        System.out.println(arrayBlockingQueue.take());//也会死死的等待取
    }
    /**
     * 超时等待
     */
    public  void  test4() throws InterruptedException {
        ArrayBlockingQueue arrayBlockingQueue=new ArrayBlockingQueue<>(3);
        arrayBlockingQueue.offer("a");
        arrayBlockingQueue.offer("a");
        arrayBlockingQueue.offer("a");
        arrayBlockingQueue.offer("a",2,TimeUnit.SECONDS);//设定超时2秒,结束等待

        arrayBlockingQueue.poll();
        arrayBlockingQueue.poll();
        arrayBlockingQueue.poll();
        arrayBlockingQueue.poll(2,TimeUnit.SECONDS);//设定超时2秒,结束等待,等待2秒后就不会取
    }

}

SynchronousQueue 同步队列

同步队列没有容量,只能往里面存一个元素,等下取,取完才能再次存下一个元素

线程池

池化技术:事先准备好一些资源,有人要用,就来我这里拿,用完之后还给我

线程池的好处

1: 、降低资源的消耗
2:提高响应的速度
3:方便管理

Executors 工具类 3大方法
package juc;

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

public class PoolDemo {
    public static void main(String[] args) {
//        ExecutorService executorService = Executors.newSingleThreadExecutor();//单个线程
//        ExecutorService executorService = Executors.newFixedThreadPool(5);//创建一个固定线程池的大小
        ExecutorService executorService = Executors.newCachedThreadPool();//可伸缩的

        try {
                for (int i = 0; i <100 ; i++) {
                executorService.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"ok");
                });
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
//                线程池用完,程序结束,关闭线程池
                executorService.shutdown();
            }

    }
}

本质3大方法都是调用了ThreadPool,7大参数

 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;
    }

自定义线程池

package juc;

import java.util.concurrent.*;

/***
 *   new ThreadPoolExecutor.AbortPolicy()  //银行满了,还有人进来,不处理这个人,抛出异常
 *   new ThreadPoolExecutor.CallerRunsPolicy() //哪里来的,回哪里  。本示例上会交给main方法执行
 *   new ThreadPoolExecutor.DiscardPolicy()   //队列满了,丢掉任务,不会抛出异常
 *    new ThreadPoolExecutor.DiscardOldestPolicy()   //队列满了,会和最早的线程去竞争一下,不会抛出异常
 */
public class PoolDemo {
    public static void main(String[] args) {
//        ExecutorService executorService = Executors.newSingleThreadExecutor();//单个线程
//        ExecutorService executorService = Executors.newFixedThreadPool(5);//创建一个固定线程池的大小
//        ExecutorService executorService = Executors.newCachedThreadPool();//可伸缩的
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                2,
                5,
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy()
        );
        try {
                for (int i = 0; i <100 ; i++) {
                    threadPoolExecutor.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"ok");
                });
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
//                线程池用完,程序结束,关闭线程池
            threadPoolExecutor.shutdown();
            }

    }
}

四种拒绝策略
在这里插入图片描述

new ThreadPoolExecutor.AbortPolicy() //银行满了,还有人进来,不处理这个人,抛出异常 new ThreadPoolExecutor.CallerRunsPolicy() //哪里来的,回哪里 。本示例上会交给main方法执行 new ThreadPoolExecutor.DiscardPolicy() //队列满了,丢掉任务,不会抛出异常 new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,会和最早的线程去竞争一下,不会抛出异常

最大的线程的大小如何定义
1:cpu密集型:几核就是几,可以保持cpu的效率最高
2:IO 密集型 。判断你程序中十分耗IO 的线程,高于这个线程数就可以了

cpu密集型示例代码

package juc;

import java.util.concurrent.*;

/***
 *   new ThreadPoolExecutor.AbortPolicy()  //银行满了,还有人进来,不处理这个人,抛出异常
 *   new ThreadPoolExecutor.CallerRunsPolicy() //哪里来的,回哪里  。本示例上会交给main方法执行
 *   new ThreadPoolExecutor.DiscardPolicy()   //队列满了,丢掉任务,不会抛出异常
 *    new ThreadPoolExecutor.DiscardOldestPolicy()   //队列满了,会和最早的线程去竞争一下,不会抛出异常
 */
public class PoolDemo {
    public static void main(String[] args) {
        System.out.println(Runtime.getRuntime().availableProcessors());
//        ExecutorService executorService = Executors.newSingleThreadExecutor();//单个线程
//        ExecutorService executorService = Executors.newFixedThreadPool(5);//创建一个固定线程池的大小
//        ExecutorService executorService = Executors.newCachedThreadPool();//可伸缩的
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                2,
                Runtime.getRuntime().availableProcessors(),
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy()
        );
        try {
                for (int i = 0; i <100 ; i++) {
                    threadPoolExecutor.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"ok");
                });
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
//                线程池用完,程序结束,关闭线程池
            threadPoolExecutor.shutdown();
            }

    }
}

四大函数式接口(必须掌握) 作用:简化编程模型

函数式接口:只有一个参数,有一个输出

package juc;

import java.util.function.Function;

/**
 * Function 函数型接口,有一个输入参数,有一个输出
 * 只要是函数式接口,都可以用lambda表达式简化
 */
public class FunctionTest {
    public static void main(String[] args) {
//        Function function = new Function<String,String>() {
//            @Override
//            public String apply(String s) {
//                return s;
//            }
//        };
        Function function1=(str)->{return  str;};
        System.out.println(function1.apply("ssss"));
    }
}

断定型接口(predicate):有一个输入参数,返回值是布尔值

/**
 * Predicate 断定型接口:有一个输入参数,返回值只能死布尔值
 */
public class PredicateTest {
    public static void main(String[] args) {
//        Predicate<String> stringPredicate = new Predicate<String>() {
//            @Override
//            public boolean test(String s) {
//                return false;
//            }
//        };
        Predicate<String> stringPredicate=(str)->{return  false;};
        System.out.println(stringPredicate.test("test"));

    }
}

Consumer消费型接口:有一个输入参数,但是没有返回值

package juc;

import java.util.function.Consumer;

/**
 * 消费型接口:有一个输入参数,没有返回值
 */
public class ConsumerTest {
    public static void main(String[] args) {
//        Consumer<String> stringConsumer = new Consumer<>() {
//            @Override
//            public void accept(String s) {
//                System.out.println(s);
//            }
//        };
        Consumer<String> stringConsumer=(str)->{return;};
        stringConsumer.accept("test2");
    }
}

Supplier 供集型接口: 没有参数,只有返回值

package juc;

import java.util.function.Supplier;

/**
 * supplier 供集型接口:没有参数,只有返回值
 */
public class SupplierTest {
    public static void main(String[] args) {
//        Supplier<Integer> integerSupplier = new Supplier<>() {
//            @Override
//            public Integer get() {
//                return 1024;
//            }
//        };
        Supplier<Integer> integerSupplier=()->{return  1024;};
        System.out.println(integerSupplier.get());

    }
}

Stream 流式计算

什么是Stream流式计算

package juc;

import java.util.Arrays;
import java.util.List;
import java.util.Locale;

/**
 * 题目要求:一分钟内完成此题,只能用一行代码实现
 * 现在有5个用户!
 * 1:ID必须是偶数
 * 2.年龄必须大于23岁
 * 3,用户名转为大写字母
 * 4,用户名字母倒着排序
 * 5.只输出一个用户
 */
public class StreamTest {
    public static void main(String[] args) {
        User u1=new User(1,"a",21);
        User u2=new User(2,"b",22);
        User u3=new User(3,"c",23);
        User u4=new User(4,"d",24);
        User u5=new User(6,"e",25);
//        集合就是存储
        List<User> list = Arrays.asList(u1, u2, u3, u4, u5);
//        计算交给流
        list.stream().filter(u->{return  u.getId()%2==0;})
                .filter(u->{return u.getAge()>23;})
                .map(u->{return u.getName().toUpperCase();})
                .sorted((uu1,uu2)->{return uu2.compareTo(uu1);})
                .limit(1)
                .forEach(System.out::println);


    }
}
class  User {
    private  int id;
    private  String name;
    private  int age;

    public User() {
    }

    public User(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
ForkJoin

什么是Forkjoin

Forkjoin在JDK1.7,并行执行任务,提高效率,大数据量

在这里插入图片描述

Forkjoin特点:工作窃取(a任务完成了,会窃取b 任务未完成的任务)

package juc;

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

public class TestForkJoin {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
//        test1(); //12274
        test3();  //328
    }
    public  static  void  test1(){
        Long sum=0L;
        long start=System.currentTimeMillis();
        for (Long i = 1L; i <10_0000_0000 ; i++) {
            sum+=i;
        }
        Long end=System.currentTimeMillis();
        System.out.println("sum="+sum+"时间:"+(end-start));
    }
    public  static  void  test2() throws ExecutionException, InterruptedException {
        Long start=System.currentTimeMillis();
        ForkJoinPool forkJoinPool =new ForkJoinPool();
        ForkJoinTask<Long> task = new ForkJoinTest(0L, 10_0000_0000L);
        ForkJoinTask<Long> submit = forkJoinPool.submit(task);
            submit.get();
        Long end=System.currentTimeMillis();
        System.out.println("时间:"+(end-start));
    }
    public  static  void  test3(){
        Long start=System.currentTimeMillis();
        //Stream并行流
        LongStream.rangeClosed(0L,10_0000_0000L).parallel().reduce(0,Long::sum);
        Long end=System.currentTimeMillis();
        System.out.println("时间:"+(end-start));
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值