//过去javase的写法
class Ticket{//资源类
//票
private int number = 30;
public synchronized void saleTicket(){
if (number > 0){
System.out.println(Thread.currentThread().getName()+"\t卖出第:"+(number--)+"\t还剩下:"+number);
}
}
}
/**
*题目:三个售票员 卖出 30张票
* 多线程编程的企业级套路+模板
* 1.在高内聚低耦合的前提下,线程 操作(对外暴露的调用方法) 资源类
*/
public class SaleTicket {
public static void main(String[] args) {
Ticket ticket = new Ticket();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 40; i++) {
ticket.saleTicket();
}
}
},"A").start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 40; i++) {
ticket.saleTicket();
}
}
},"B").start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 40; i++) {
ticket.saleTicket();
}
}
},"C").start();
}
}
//利用lock写法 lock相较于synchronized较为灵活, 而且锁的范围更少, 有点类似于操作系统的信号量
public class CurrentTicket {
public static void main(String[] args) {
Ticket ticket = new Ticket();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i <= 40; i ++)
ticket.saleTicket();
}
}, "a").start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i <= 40; i ++)
ticket.saleTicket();
}
}, "b").start();
//写成lamb表达式
new Thread(()->{for (int i = 1; i <= 40; i++) ticket.sale();},"A").start();
new Thread(()->{for (int i = 1; i <= 40; i++) ticket.sale();},"B").start();
new Thread(()->{for (int i = 1; i <= 40; i++) ticket.sale();},"C").start();
}
}
class Ticket{
private int count = 50;
private Lock lock = new ReentrantLock();
public void saleTicket(){
lock.lock();
try {
if (count > 0){
System.out.println(Thread.currentThread().getName() + count);
count --;
}
} finally {
lock.unlock();
}
}
}
//什么意思呢
interface Foo{
int div ();
}
//我们就可以这么做
Foo f = () -> {写实现; return 值;};
f.div();即可
// 对于有返回值有参数的
interface Foo{
int div (int a, int b);
}
Foo f = (a, b) -> {写实现; return 值};
f.div(1, 2);就可以
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author xiaofei
* @create 2021-07-28 9:53
*/
/*
* 题目: 现在两个线程, 可以操作初始值位零的一个变量,
* 实现一个进程对变量加一, 一个线程对改变量减一
* 实现交替, 来10轮, 变量初始值为零
*
*
* 1、高内聚低耦合, 线程操作资源类
* 2、判断/干活/通知
* 3、多线程交互中, 必须要防止多线程的续集唤醒, 也即 (判断使用while不
* 能用if)
* 4、标志位
* 唤醒的时候还必须在判断
* */
class AirConditioner {
private int num = 0;
private Lock lock = new ReentrantLock();
public synchronized void add() throws InterruptedException {
//这种情况会出错的原因是线程被唤醒的时侯就不需要在拍段一次条件了故在面对超过两个线程的时候就出现错误
// if (num != 0) this.wait();
// num ++;
// System.out.println(Thread.currentThread().getName() + " " + num);
//
// this.notifyAll();
//第一种解决办法
while (num != 0) this.wait();
num ++;
System.out.println(Thread.currentThread().getName() + " " + num);
this.notifyAll();
//第二种解决办法 说到底都是 让其唤醒的时候在经历一次判断 另外这样写可能打出来的结果可能不是40行
// 因为被唤醒之后就不是去去执行本次的操作而是直接本次操作结束 执行 i++ 了
// if (num == 0) {
// num ++;
// System.out.println(Thread.currentThread().getName() + " " + num);
// this.notifyAll();
// }else
// this.wait();
}
public synchronized void sub() throws InterruptedException {
while (num == 0) this.wait();
num --;
System.out.println(Thread.currentThread().getName() + " " + num);
this.notifyAll();
// if (num == 1) {
// num --;
// System.out.println(Thread.currentThread().getName() + " " + num);
// this.notifyAll();
// }else
// this.wait();
}
}
public class ThreadWaitNotifyDemo {
public static void main(String[] args) throws Exception{
AirConditioner airConditioner = new AirConditioner();
new Thread(() -> {
try {
// for (int i = 0; i < 10; i ++) airConditioner.sub();
while (true) airConditioner.sub();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "B").start();
new Thread(() -> {
try {
// for (int i = 0; i < 10; i ++) airConditioner.add();
while (true) airConditioner.sub();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "A").start();
new Thread(() -> {
try {
// for (int i = 0; i < 10; i ++) airConditioner.add();
while (true) airConditioner.add();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "c").start();
new Thread(() -> {
try {
// for (int i = 0; i < 10; i ++) airConditioner.sub();
while (true) airConditioner.add();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "d").start();
}
}
class AirConditioner {
private int num = 0;
private Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
public void add() throws InterruptedException {
lock.lock();
try {
while (num != 0) condition.await();
num ++;
System.out.println(Thread.currentThread().getName() + " " + num);
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void sub() throws InterruptedException {
lock.lock();
try {
while (num == 0) condition.await();
num --;
System.out.println(Thread.currentThread().getName() + " " + num);
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
/*
* 多线程之间按顺序调用, 实现A -> B -> C
* 三个线程启动, 要求如下:
* A 打印5次 B 打印10次, CC打印15次
* 接着
* AA打印5次, BB打印10次, CC打印15次
* 来10轮
* 下订单 -> 减库存 -> 调支付
*
* synchronized 它最大的缺点就是不能精确唤醒某个线程
* lock 它灵活可以多个锁精确唤醒
* 可以让某个锁放开当前线程
* 非常像操作系统的信号量的传参, 当前参数被那个锁给await了那么就只能用这把锁把他唤醒,
* 跟线程同步有关操作系统
* */
class Print{
private int num = 1; // 1:A 2:B 3 C
private Lock lock = new ReentrantLock();
Condition A = lock.newCondition(); //用来锁A的
Condition B = lock.newCondition(); // 用来锁B的
Condition C = lock.newCondition(); //用来锁C的
public void print(int sign){
if (sign == 1){
lock.lock();
try {
while (num != 1){
A.await();
}
for (int i = 0; i < 5; i ++){
System.out.println(Thread.currentThread().getName() + " " + i);
}
num ++;
B.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}else if (sign == 2){
lock.lock();
try {
while (num != 2){
B.await();
}
for (int i = 0; i < 10; i ++){
System.out.println(Thread.currentThread().getName() + " " + i);
}
num ++;
C.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}else {
lock.lock();
try {
while (num != 3){
C.await();
}
for (int i = 0; i < 15; i ++){
System.out.println(Thread.currentThread().getName() + " " + i);
}
num = (num + 1) % 3;
A.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
public class ThreadOrderAccess {
public static void main(String[] args) {
Print print = new Print();
new Thread(
() -> {
for (int i = 0; i < 10; i ++) print.print(1);
}, "A"
).start();
new Thread(
() -> {
for (int i = 0; i < 10; i ++) print.print(2);
}, "B"
).start();new Thread(
() -> {
for (int i = 0; i < 10; i ++) print.print(3);
}, "C"
).start();
}
}
/*
*
* 题目:多线程8锁
* 1、两个普通的同步方法 先打印邮件还是sms :邮件
* 2、邮件方法暂停3秒钟, 请问先打印那个: 邮件
* 3、邮件方法暂停3秒钟 新增一个普通方法hello()和发邮件, 先打印邮件还是hello : hello
* 4、两部手机一个发邮件一个发短信 发短信
* 5、两个静态同步方法、同一部手机先打印那个 邮件
* 6、两个静态同步方法 两部手机 : 邮件
* 7、一个静态同步方法, 一个普通同步方法 同一部手机 : SMS
* 8、一个静态同步方法, 一个普通同步方法 2部手机 : SMS
*
* 想两个拿同一个手机 一个想打电话一个想发消息, 同一时间是不是只能有一个人拿到这部手机
* 笔记:
* 一个对象里面如果有多个synchronized. 某个时刻内, 只要有一个线程去调用其中的一个synchronized方法
* 其他线程都只能等待, 换句话说, 某个时刻内, 只能有一个对象去访问同一个资源类中的synchronized方法
* 锁的是当前对象this, 被锁定后, 其他线程都不能进入到当前对象的其他的synchronized方法
* 加个普通方法后和同步锁无关
* 换成两个对象之后, 不是同一把锁了, 故无关
* 都换成静态同步方法的时候 对于静态方法的锁是 本类.class
*
* 静态同步方法于非静态同步方法之间是不会有竞态条件的
* 但是一旦一个静态同步方法获取锁后, 其他的静态方法都必须等待该方法释放锁后才能获取锁
* 总之 对于锁相同的时候同时只能有一个线程访问
*
* */
class Phone{
public static synchronized void sendEmail() throws InterruptedException {
Thread.sleep(3000);
System.out.println("sendEmail");
}
public synchronized void sendSmS(){
System.out.println("sendSMS");
}
public void hello(){
System.out.println("hello");
}
}
public class Lock8 {
public static void main(String[] args) {
Phone phone1 = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
try {
phone1.sendEmail();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "A").start();
new Thread(() -> {
phone2.sendSmS();
}, "B").start();
new Thread(() -> {
phone1.hello();
}, "C").start();
}
}
/*
* 笔记:
* 写时复制
* CopyOnWrite 容器即写时复制的容器, 往一个容器添加元素的时候, 不直接往当前容器的object[]添加元素, 而是先将当前容器Object[]
* 进行复制出一个新的容器object[] newElements, 让后新的容器object[] newElements里添加元素, 添加元素之后,
* 在将原容器的引用指向心的容器 setArray(newElements) 这样做的好处时可以对CopyOnWrite容器进行并发的读,
* 而不需要加锁, 因为当前容器不会添加任何元素, 所以CopyOnWrite容器也是一种读写分离的思想, 读和写不同的容器
* public boolean add(E e) {
* final ReentrantLock lock = this.lock;
* lock.lock();
* try {
* Object[] elements = getArray();
* int len = elements.length;
* Object[] newElements = Arrays.copyOf(elements, len + 1);
* newElements[len] = e;
* setArray(newElements);
* return true;
* } finally {
* lock.unlock();
* }
* }
* HashSet底层就是hashmap add方法add一个值就是hashmap的key, value是写死的Object
* hashMap 底层是一个Node类型的数组加链表+红黑树, 他是使用的拉链发实现的hash表, 数组长度起始为16 负载因子0.75
* 链表超过8就是变成红黑树。
*
* 题目: 请举例说明集合类是不安全的
* ArrayList hashSet hashmap 是线程不安全的
* vector 是线程安全的 only-one 不在乎性能只在乎 线程安全不安全
* 1、故障现象
* 会出现java.utils.concurrentModificationException
*
* 2、导致原因
* 并发修改异常
* 3、解决方案
* 1、 vector
* 2、 Collections.synchronizedList
* 3、 CopyOnWriteArrayList 多线程用这个
* 写的时候复制一份, 让读跟写分离
* Object[] newElements = Arrays.copyOf(elements, len + 1);
* newElements[len] = e;
* setArray(newElements);
* 4、CurrentHashMap -> hashMap
* 5、LinkedList -> ConcurrentLinkedQueue
* 6、hashSet 他的底层就是HashMap所以
*
* 4、优化建议 (同样的错误, 不出现第二次)
*
* */
public class NotSafeDemo {
public static void main(String[] args) {
setNoteSafe();
}
public static void MapNotSafe(){
// Map map = new HashMap<>();
Map<String, String> map = new ConcurrentHashMap<>();
}
public static void setNoteSafe (){
// Set set = new HashSet<>();
Set<String> set = new CopyOnWriteArraySet<>();
for (int i = 1; i <= 30; i++) {
new Thread(() ->
{
set.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(set);
}, String.valueOf(i)).start();
}
}
public static void listNotSafe (){
// List list = new ArrayList();
// List
// List
List<Object> list = new CopyOnWriteArrayList<>();
for (int i = 1; i <= 30; i++) {
new Thread(() ->
{
list.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(list);
}, String.valueOf(i)).start();
}
}
}
/*
* 多线程中, 第三种获得多线程的方式
*
* 实现runnable接口和Callable的异同
* 1、落地方法不同一个是run一个叫call'
* 2、callable有异常
* 3、callable 有返回值 泛型是什么就返回什么
* 4、callable 支持泛型
*
* get 要放在最后一行
* */
class MyThread1 implements Runnable{
@Override
public void run() {
}
}
class MyThread2 implements Callable<Integer>{
@Override
public Integer call() throws Exception {
System.out.println("aaaaa");
Thread.sleep(1000);
return 1024;
}
}
public class CallableDemo {
public static void main(String[] args) {
// 一个futureTask不管多少个线程调都只会被调用一次
FutureTask futureTask = new FutureTask(new MyThread2());
try {
//以下两个线程只会出现一次调用
new Thread(futureTask,"A").start();
new Thread(futureTask,"B").start();
Object o = futureTask.get(); //尽量放在后面在取, 否者会导致程序堵塞
System.out.println(o);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
*
* CountDownLatch 主要有两个方法, 当一个或多个线程调用await方法, 这些线程回阻塞
* 其他线程调用countDown方法会将计数器减一, 调用countDown方法的线程不会阻塞
* 当计数器变为0的时候, 被await的方法才会唤醒继续执行
*
*/
public class CountDownLatchDemo {
// 正确做法 实际上我感觉我还没看源码呢, 这个类似于操作系统的P,V操作实现线程同步
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() + "同学离开");
countDownLatch.countDown();
}, String.valueOf(i)).start();
}
//这个证明唤醒所有
new Thread(() ->{
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "同学离开");
}, "test").start();
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + "班长走了");
}
// 要实现班长要比其他同学先走
//结果
/*
* 1同学离开
main班长走了
3同学离开
2同学离开
6同学离开
5同学离开
4同学离开
* */
void errorOptions(){
for (int i = 1; i <= 6; i++) {
new Thread(() ->{
System.out.println(Thread.currentThread().getName() + "同学离开");
}, String.valueOf(i)).start();
}
System.out.println(Thread.currentThread().getName() + "班长走了");
}
}
/*
*
* CyclicBarrier
*
* 刚好够多少个数量才能进行下去, 人够了才能开会
* */
public class CyclicBarrierDemo {
//结果 做加法 达到多少个线程才会执行
/*
* 第1个龙珠
第3个龙珠
第5个龙珠
第6个龙珠
第4个龙珠
第2个龙珠
召唤神龙
* */
public static void main(String[] args) {
//CyclicBarrier(int parties, Runnable barrierAction)
CyclicBarrier cyclicBarrier = new CyclicBarrier(6, () ->{
System.out.println("召唤神龙");
});
for (int i = 1; i <= 6; i++) {
final int t = i;
new Thread(() -> {
System.out.println("第" + t + "个龙珠");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(cyclicBarrier.getParties());
}, String.valueOf(i)).start();
}
}
}
/*
*
* 多个线程同时读一个资源类没有任何问题, 所以为了满足并发量, 读取共享资源应该可以同时进行
* 但是
* 如果有一个线程想去写共享资源, 就不能应该再有其他线程可以对该资源进行读写
* 小结
* 读读 能共存
* 读写 不能共存
* 写写 不能共存
*
* 加读写锁的时候, 写入的时候不能背加塞, 一次性成功完成 , 也完成了数据的完成性
* */
class MyCache{
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() + "开始写入");
try {
TimeUnit.MILLISECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
map.put(key, value);
System.out.println(Thread.currentThread().getName() + "写成功" + key);
} finally {
readWriteLock.writeLock().unlock();
}
}
public Object read (String key){
readWriteLock.readLock().lock();
Object o;
try {
System.out.println(Thread.currentThread().getName() + "开始读");
try {
TimeUnit.MILLISECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
o = map.get(key);
System.out.println(Thread.currentThread().getName() + "读成功" + o);
} finally {
readWriteLock.readLock().unlock();
}
return o;
}
}
public class ReadWriteLockDemo {
public static void main(String[] args) {
MyCache myCache = new MyCache();
for (int i = 1; i <= 6; i++) {
final int t = i;
new Thread(() -> {
myCache.put(t + "", t);
}, String.valueOf(i)).start();
}
for (int i = 1; i <= 6; i++) {
final int t = i;
new Thread(() -> {
myCache.read(t + "");
}, String.valueOf(i)).start();
}
}
}
/*
* 阻塞队列
* 1、数据结构 栈和队列
*
* 2、阻塞队列
* 2、1 阻塞 必须要阻塞/不得不阻塞
*
*
* */
public class BlockingQueueDemo {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
// //true
// System.out.println(blockingQueue.add("a"));
// System.out.println(blockingQueue.add("b"));
// System.out.println(blockingQueue.add("c"));
// //再加就抛异常, 队列已满
System.out.println(blockingQueue.add("d"));
//得到队首
// System.out.println(blockingQueue.element());
//
// // 结果 a b c
// System.out.println(blockingQueue.remove());
// System.out.println(blockingQueue.remove());
// System.out.println(blockingQueue.remove());
// //空 抛出异常
// // System.out.println(blockingQueue.remove());
// 队不满返回true
// System.out.println(blockingQueue.offer("a"));
// System.out.println(blockingQueue.offer("b"));
// System.out.println(blockingQueue.offer("c"));
// // 队满返回false
// System.out.println(blockingQueue.offer("x"));
//
// System.out.println(blockingQueue.poll());
// System.out.println(blockingQueue.poll());
// System.out.println(blockingQueue.poll());
// //队空 返回空
// System.out.println(blockingQueue.poll());
//没有返回值
// blockingQueue.put("a");
// blockingQueue.put("a");
// blockingQueue.put("a");
// //队满 等待阻塞直到队有空间
blockingQueue.put("a");
//
// System.out.println(blockingQueue.take());
// System.out.println(blockingQueue.take());
// System.out.println(blockingQueue.take());
// //队空阻塞
// System.out.println(blockingQueue.take());
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("b"));
//队满 阻塞一定时间如果还不为空就走i
System.out.println(blockingQueue.offer("z", 3L, TimeUnit.SECONDS));
}
}
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
public class MyThreadPoolDemo {
public static void main(String[] args) {
//得到运行环境的cpu核心数
System.out.println(Runtime.getRuntime().availableProcessors());
// ExecutorService threadPool = new ThreadPoolExecutor( 2, 5, 2L,
// TimeUnit.MILLISECONDS,
// new LinkedBlockingQueue<>(3),
// Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
/*
* 用callerRunsPolicy 这个策略 当出现 等待区满了, max也满了 无法接续为新任务服务 就回退给调用者
* pool-1-thread-1办理业务
pool-1-thread-3办理业务
pool-1-thread-3办理业务
main办理业务
pool-1-thread-2办理业务
pool-1-thread-5办理业务
pool-1-thread-3办理业务
pool-1-thread-1办理业务
pool-1-thread-4办理业务
* */
// ExecutorService threadPool = new ThreadPoolExecutor( 2, 5, 2L,
// TimeUnit.MILLISECONDS,
// new LinkedBlockingQueue<>(3),
// Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
// 10进8 超过就直接放弃 (前提允许任务丢失)
// ExecutorService threadPool = new ThreadPoolExecutor( 2, 5, 2L,
// TimeUnit.MILLISECONDS,
// new LinkedBlockingQueue<>(3),
// Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardPolicy());
// 抛弃等待队列中等待时间最长的 也就是队首
ExecutorService threadPool = new ThreadPoolExecutor( 2, 5, 2L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(3),
Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardOldestPolicy());
try {
//模拟10个人办理银行办理业务 等待区满了, max也满了 无法接续为新任务服务 就拒绝(拒绝策略)
for (int i = 1; i <= 9; i++) {
// Thread.sleep(5); //加上这个就不会出现超过8个线程就拒接, 因为有的就完成了
threadPool.execute(() -> {
System.out.println(Thread.currentThread().getName() + "办理业务");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
threadPool.shutdown();
}
}
public void init(){
//一个池中有几个线程
// ExecutorService threadPool = Executors.newFixedThreadPool(5);
//一个池中只有一个线程
// ExecutorService threadPool = Executors.newSingleThreadExecutor();
//执行很多短期异步任务, 线程池根据需要创建新线程, 但再先前构建的线程可用时将重用他们。 可扩容。
ExecutorService threadPool = Executors.newCachedThreadPool();
try {
//模拟10个人办理银行办理业务
for (int i = 1; i <= 10; i++) {
threadPool.execute(() -> {
System.out.println(Thread.currentThread().getName() + "办理业务");
});
}
} finally {
threadPool.shutdown();
}
}
}
public class Funcations {
public static void main(String[] args) {
Consumer<String> consumer = s -> {
System.out.println(s);
};
consumer.accept("Aaaa");
Supplier<String> supplier = () -> {return "aaa";};
System.out.println(supplier.get());
Function<String, Integer> function = s -> {return Integer.parseInt(s);};
System.out.println(function.apply("234"));
Predicate<String> predicate = s -> {return !s.isEmpty();};
System.out.println(predicate.test("aaaa"));
}
}
public class Funcations {
/*
* 按照给定的数据, 找出同时满足以下条件的用户, 也即以下条件全部满足
* 偶数Id且年龄大于24且用户名转为大写且用户名字母倒序
* 只输出一个用户名字
* */
public static void main(String[] args) {
User user1 = new User(11, "a", 23);
User user2 = new User(12, "b", 24);
User user3 = new User(13, "c", 22);
User user4 = new User(14, "d", 28);
User user5 = new User(16, "e", 26);
List<User> list = Arrays.asList(user1, user2, user3, user4, user5);
//filter过滤 map把每个返回值重新映射倒list sort排序 count计数
// list.stream()
// .filter(t -> {return t.getId() % 2 == 0 && t.getAge() > 24;})
// .map(s -> {return s.getUsername().toUpperCase();})
// .sorted((o1, o2) -> {return o2.compareTo(o1);}).limit(1)
// .forEach(System.out::println);
//这个省略大括号
list.stream()
.filter(t -> t.getId() % 2 == 0 && t.getAge() > 24)
.map(s -> {return s.getUsername().toUpperCase();})
.sorted((o1, o2) -> {return o2.compareTo(o1);}).limit(1)
.forEach(System.out::println);
fun();
}
//四大函数式接口
static void fun(){
Consumer<String> consumer = s -> System.out.println(s);
consumer.accept("Aaaa");
Supplier<String> supplier = () ->"aaa";
System.out.println(supplier.get());
Function<String, Integer> function = s -> {return Integer.parseInt(s);};
System.out.println(function.apply("234"));
Predicate<String> predicate = s -> {return !s.isEmpty();};
System.out.println(predicate.test("aaaa"));
}
}
class User{
private Integer id;
private String username;
private Integer age;
public User() {
}
public User(Integer id, String username, Integer age) {
this.id = id;
this.username = username;
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", age=" + age +
'}';
}
}
/*
*
* 计算0 - 100进行分支计算
* */
class MyTask extends RecursiveTask<Integer>{
private static final Integer ADJUST_VALUE = 10;
private int begin;
private int end;
private int result;
@Override
protected Integer compute() {
if (end - begin <= ADJUST_VALUE){
for (int i = begin; i <= end; i ++) {
result += i;
}
}else {
int middle = (end + begin) / 2;
MyTask task01 = new MyTask(begin, middle);
MyTask task02 = new MyTask(middle + 1, end);
task01.fork();
task02.fork();
result += task01.join() + task02.join();
}
return result;
}
public MyTask(int begin, int end) {
this.begin = begin;
this.end = end;
}
}
public class ForkJoinDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyTask myTask = new MyTask(0, 100);
ForkJoinPool threadPool = new ForkJoinPool();
ForkJoinTask<Integer> submit = threadPool.submit(myTask);
System.out.println(submit.get());
threadPool.shutdown();
}
}
public class CompletableFutureDemo {
public static void main(String[] args) throws Exception {
CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(
() -> {
System.out.println("*****没有返回值");
});
completableFuture.get();
//有返回值的异步
CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(
() -> {
System.out.println(Thread.currentThread().getName() + "有返回值");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int age = 10 / 0;
return 1024;
}
);
System.out.println("aaaa"); // 这个aaa先显示证明的却时异步的
// 没有异常上一个分支, 有就走exceptionally分支
System.out.println(completableFuture2.whenComplete((t, u) -> {
System.out.println(t);
System.out.println(u);
}).exceptionally(f -> {
System.out.println(f.getMessage());
return 4444;
}).get());
}
}
在本次视频中周阳老师讲了juc常见的类, 以及如何使用,另外也讲了jdk8新出的stream以及函数式编程, 让我们大致了解了juc, 如果想学详细的推荐学 黑马那个JUC高级