一、等待唤醒机制

1、线程间通信

  • 多个线程处理同一个资源,就存在线程通信问题(线程间存在竞争与协作机制)
  • 为什么处理:为了 保证多个线程有规律地完成同一任务
  • 如何处理:避免对共享变量争夺,需要等待唤醒机制,保证各线程有效利用资源

2、等待唤醒机制

  • 定义:A线程执行操作后进入等待(wait)状态,等B线程执行完指定代码后再将A唤醒(notify)/唤醒多个线程(notifyAll)
  • 注意:
    • wait和notify需要由同一个锁对象Obj调用
    • 锁对象可以是任意对象<? extends Object>
    • wait和notify必须在同步代码块或同步方法中使用(必须由锁对象调用)

3、生产者与消费者问题【线程之间的通信】

  • 等待唤醒机制就是生产者与消费者问题

二、线程池

1、概念

  • 使用时频繁创建线程会降低系统效率
  • 实际上是一个集合,建议使用LInkedList
  • 好处:降低资源消耗、提高响应速度(无需每次进行线程创建)、可以根据系统承受能力调整工作线程数目

2、使用

  • 线程池的工厂类java.util.concurrent.Executors,用于生成线程池

    • 静态方法:ExecutorService newFixedThreadPool(int nThreads)
  • 线程池的接口java.util.concurrent.ExecutorService,获取接口调用start方法
    • submit(Runnable task):提交线程任务用于执行
    • shutdown():销毁线程池
  • 使用步骤:
package com.liujinhui.Day1101WaitAndNotify;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPool {
public static void main(String[] args) {
// 1.使用工厂类java.util.concurrent.Executors的静态方法newFixedThreadPool生成一个指定数量的线程池
ExecutorService es= Executors.newFixedThreadPool(2);
// 3.调用ExecutorService中的方法submit,传递线程任务,开启线程,执行run方法
es.submit(new RunnableImpl());
//线程池会一直开启,使用完了线程,会自动把线程归还给线程池,线程可以继续使用
es.submit(new RunnableImpl());
es.submit(new RunnableImpl());
es.shutdown();
es.submit(new RunnableImpl());//线程池没有了,就不能获取线程了
}}

三、Lambda表达式

函数内调用了某接口的抽象方法,参数为接口名

1、函数式编程思想

  • 强调解决问题得到结果,不重视具体解决的过程
  • 面向对象:强调可以解决问题的对象

2、冗余的Runnable代码

  • 函数内调用Runnable的run方法
  • 原来:实现类重写Runnable的run方法
  • 简化:匿名内部类

3、编程思想转换

  • 将面向对象编程思想转换为函数式编程思想
  • 与面向过程相比,更注重结果而非过程
  • 真实目的 :传递一段代码

4、Lambda写法(JDK8的新特性)

  • 打开了函数式编程思想的大门
package com.liujinhui.Day1101WaitAndNotify;
public class Demo02Lambda {
public static void main(String[] args) {
//之前,匿名内部类
new Thread(new Runnable(){
@Override
public void run(){
System.out.println(Thread.currentThread().getName()+"正在执行接口");
}
}).start();
//现在,使用Lambda表达式实现多线程
new Thread(()->
System.out.println(Thread.currentThread().getName()+"正在执行接口")
).start();
}
}

5、Lambda标准格式

package com.liujinhui.Day1101WaitAndNotify;
import java.util.Arrays;
import java.util.Comparator;
public class Demo01Arrays {
public static void main(String[] args) {
//使用数组存储多个Person对象
Person[] person={new Person("柳岩",38),
new Person("迪丽热巴",18),
new Person("古力娜扎",19)};
//升序排列,使用Arrays的sort方法
Arrays.sort(person, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge()-o2.getAge();
}
});
for (Person person1 : person) {
System.out.println(person1);
}
//使用Lambda表达式,简化匿名内部类
Arrays.sort(person,(Person o1,Person o2)->{return o1.getAge()-o2.getAge();});
for (Person p : person) {
System.out.println(p);
}
}
}

6、Lambda省略格式

  • 可省略内容:可以根据上下文推导出来的

    • 参数列表类型
    • 参数列表的个数为一个时,可省略括号
    • 省略大括号、return和分号
  • 要省略必须一起省略
       //使用Lambda表达式,简化匿名内部类
Arrays.sort(person,(Person o1,Person o2)->{return o1.getAge()-o2.getAge();}); //省略优化Lambda
Arrays.sort(person,(o1,o2)-> o1.getAge()-o2.getAge());

7、使用前提

  • 函数式接口(接口中只有一个抽象方法),如Runnable的run方法、Comparator的sort方法
  • 具有上下文推断(方法的参数类型必须为Lambda对应的接口类型)

【Java SE进阶】Day07 等待与唤醒案例、线程池、Lamdba表达式的更多相关文章

  1. 等待唤醒机制----线程池----lambda表达式

    1.等待唤醒机制 1.1线程间通信 概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同. 比如:线程A用来生成包子的,线程B用来吃包子的,包子可以理解为同一资源,线程A与线程B处理的 ...

  2. Java第三阶段学习(七、线程池、多线程)

    一.线程池 1.概念: 线程池,其实就是一个容纳多个线程的容器,其中的线程可以重复使用,省去了频繁创建线程对象的过程,无需反复创建线程而消耗过多资源,是JDK1.5以后出现的. 2.使用线程池的方式- ...

  3. Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)

    Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...

  4. Java 面试题 三 <JavaWeb应用调优线程池 JVM原理及调优>

    1.Java Web应用调优线程池 不论你是否关注,Java Web应用都或多或少的使用了线程池来处理请求.线程池的实现细节可能会被忽视,但是有关于线程池的使用和调优迟早是需要了解的.本文由浅入深,介 ...

  5. Java并发包源码学习系列:线程池ScheduledThreadPoolExecutor源码解析

    目录 ScheduledThreadPoolExecutor概述 类图结构 ScheduledExecutorService ScheduledFutureTask FutureTask schedu ...

  6. java多线程同步,等待,唤醒

    notify().notifyAll().wait()属于java.lang.Object,java.lang.Thread也是Object,自然也有上述方法: sleep().interrupt() ...

  7. JAVA笔记14__多线程共享数据(同步)/ 线程死锁 / 生产者与消费者应用案例 / 线程池

    /** * 多线程共享数据 * 线程同步:多个线程在同一个时间段只能有一个线程执行其指定代码,其他线程要等待此线程完成之后才可以继续执行. * 多线程共享数据的安全问题,使用同步解决. * 线程同步两 ...

  8. Java多线程总结(二)锁、线程池

    掌握Java中的多线程,必须掌握Java中的各种锁,以及了解Java中线程池的运用.关于Java多线程基础总结可以参考我的这篇博文Java多线程总结(一)多线程基础 转载请注明出处——http://w ...

  9. Java多线程(三)锁对象和线程池

    1:锁(Lock) 1.1       java提供了一个锁的接口,这个锁同样可以达到同步代码块的功能,API文档上说使用锁比使用synchronized更加灵活. 1.2       如何使用这个“ ...

随机推荐

  1. 第六章:Django 综合篇 - 2:核心配置项

    Django的默认配置文件中,包含上百条配置项目,其中很多是我们'一辈子'都不碰到或者不需要单独配置的,这些项目在需要的时候再去查手册. 强调:配置的默认值不是在settings.py文件中!不要以为 ...

  2. docker 生成mysql镜像启动时自动执行sql

    文章转载自:https://www.jianshu.com/p/12fc253fa37d 在docker 创建 mysql 容器时,往往需要在创建容器的过程中创建database 实例,代码如下: # ...

  3. Kibana管理

    这里是用来管理您的 kibana 运行时配置的地方,包括初始化配置和后续的索引模式配置.高级设置等.您可以调整 kibana 自身的行为,也可以编辑您通过 kibana 保存的查询.视图.仪表板等各种 ...

  4. linux系统安装Confluence

    转载网址:https://blog.yupaits.com/blog/record/linux-confluence.html#安装步骤 Confluence简介 Confluence是一个专业的企业 ...

  5. 使用Receiver接收告警信息

    告警接收器可以通过以下形式进行配置: receivers: - <receiver> ... 每一个receiver具有一个全局唯一的名称,并且对应一个或者多个通知方式: name: &l ...

  6. 类和实例,super()函数

    class Foo: def __init__(self, name): self.name = name def ord_func(self): """定义实例方法,至 ...

  7. 9. Fluentd部署:日志

    Fluentd是用来处理其他系统产生的日志的,它本身也会产生一些运行时日志.Fluentd包含两个日志层:全局日志和插件级日志.每个层次的日志都可以进行单独配置. 日志级别 Fluentd的日志包含6 ...

  8. 【面试题】Vue2动态添加路由 router.addRoute()

    Vue2动态添加路由 点击打开视频讲解更加详细 场景: 一般结合VueX和localstorage一起使用 router.addRoutes vue-router4后 已废弃:使用 router.ad ...

  9. C#-6 运算符和语句

    一 运算符重载 可以重定义或重载 C# 中内置的运算符. 重载运算符是具有特殊名称的函数,是通过关键字 operator 后跟运算符的符号来定义的. public static Box operato ...

  10. TF-GNN踩坑记录(二)

    引言 最近在尝试构建GraphTensor时,尝试把默认的特征名hidden_state改成其他时,出现了奇怪的报错. 报错 WARNING:tensorflow:Gradients do not e ...