A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 小石姐姐 于 2018-8-9 11:30 编辑



等待与唤醒机制:
一个线程进行了规定操作后, 就进入等待状态( wait() ), 等待其他线程执行完他们的指定代码过后, 再将其唤醒( notify())
在有多个线程进行等待时, 如果需要, 可以使用 notifyAll() 来唤醒所有的等待线程
wait/notify 就是线程间的一种协作机制, 用于解决线程间通信的问题
等待唤醒中的方法
java.lang.Object类:
// 成员方法 (只能通过"锁对象"调用)

[AppleScript] 纯文本查看 复制代码
wait():让使用该锁的线程进入无限等待状态,直到有其他线程通过相同的锁对象唤醒(notify/notifyAll)
notify():随机唤醒一个处于等待状态的一个线程
notifyAll():唤醒所有在同一个锁对象上处于等待状态的线程
锁对象必须是多个线程共同的唯一一个
方法只能通过”锁对象”调用
从waiting恢复过来的线程
如果获取不到锁,进入BLOCKED 锁阻塞状态
如果获取到锁,进入RUNNABLE 可运行状态
调用 wait() 和 notify() 需要注意的细节:
[AppleScript] 纯文本查看 复制代码
1. wait() 与 notify() 必须要由"同一个锁对象"调用
因为对应的锁对象可以通过 notify() 唤醒使用同一个锁对象调用的 wait() 后的线程
2. wait() 与 notify() 是属于Object类的方法
因为锁对象可以是任意对象, 而任意对象的所属类都是继承了Object类的
3. wait() 与 notify() 必须要在"同步代码块"或者是"同步方法"中使用
因为必须要通过锁对象调用这2个方法
线程池
普通创建线程方式的缺点:
"创建"线程和"销毁"线程都是比较占用内存和CPU的操作.
对于一些数量多, 执行时间短的任务, 频繁的创建和销毁线程来执行, 会降低程序运行效率.
线程池概念:
一个容纳多个线程的容器
线程池可以解决的问题:
其中的线程可以反复使用, 省去了频繁创建线程对象的操作, 无需反复创建线程而消耗过多资源
线程池的工作原理:
提前创建好多个线程对象, 放在集合中. 多个任务来了反复使用这些线程对象来执行
线程池的代码实现
[AppleScript] 纯文本查看 复制代码
java.util.concurrent.Executors类: 线程池工厂类, 用于管理线程池
// 静态方法:

[AppleScript] 纯文本查看 复制代码
static ExecutorService newFixedThreadPool(int nThreads): 创建固定数量线程的线程池(常用)
java.util.concurrent.ExecutorService接口: 真正执行任务的线程池服务
// 成员方法:

[Java] 纯文本查看 复制代码
Future submit(Runnable task): 提交一个Runnable任务
void shutdown(): 通知线程执行完任务后关闭. 如不调此方法, 则线程执行完任务后仍在运行以        便重复使用
线程池的创建和使用步骤Executors类
[Java] 纯文本查看 复制代码
1. 使用Executors的静态方法 newFixedThreadPool(int nThreads) 创建线程池ExecutorService
    例ExecutorService executorService = Executors.newFixedThreadPool(2);
2. 创建一个任务类, 实现Runnable接口, 重写run()方法
3. 调用ExecutorService对象的 submit(Runnable task) 方法, 传递任务给线程池, 执行任务
    例:executorService.submit(new RunnableImpl());
4. 调用ExecutorService对象的 shutdown() 方法, 销毁线程池 (不建议执行)
    例:executorService.shutdown();
函数式编程思想:Lambda表达式
面向对象:强调用什么对象做什么事(注重语法形式)
函数式:强调做事(不在乎对象是谁,重写什么方法)
优点:简化代码编写
Lambda表达式
[Java] 纯文本查看 复制代码
( ) ‐> System.out.println(“多线程任务执行!”);
Lambda标准格式
三部分组成
一些参数( )
接口中抽象方法的参数列表. 没参数就空着; 有参数就写, 多个参数用逗号分隔
一个箭头->
将参数传递给方法体
一段代码{}
重写接口抽象方法的方法体
标准格式为:
(参数列表) - > { 一段代码 };
解释说明格式:
( ):接口中抽象方法的参数列表,没有参数,就空着,有参数就写,多个参数用逗号分隔
-> 将参数传递给方法体
{ }:重写接口的抽闲个方法的方法体
例:
[Java] 纯文本查看 复制代码
new Thread(()->{
            System.out.println(Thread.currentThread().getName() + "新线程 创建了");
 }).start();
               
Lambda代替函数式接口的匿名内部类
Lambda 使用前提
1. 使用Lambda必须具有函数式接口,且要求接口中有且仅有一个抽象方法。(也称为"函数式接口")
无论是JDK内置的 Runnable 、 Comparator 接口还是自定义的接口,只有当接口中的抽象方法存在且唯一时,才可以使用Lambda。
2. 使用Lambda必须具有上下文推断。
也就是方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。
(简而言之: 作为参数类型的接口, 必须是函数式接口)
Lambda 省略格式
省略原则:可推导的都可省略 (凡是能根据前后代码能猜测出来的代码, 都可以省略不写)
可以省略的内容:
1(参数列表):括号中参数列表的数据类型,可以省略不写
2(参数列表):括号中的参数如果只有一个,那么类型( )都可以省略
3{一些代码}:如果只有一条代码,则”大括号”,”return”,”分号”都可以”一起省略”

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马