Java之线程池和Lambda表达式
线程池和lambda表达式
学习线程池和lambda表达式的理解
补充一个知识点(单例设计模式)
在多线程中,我们只需要一个任务类,为了防止创建多个任务类,这个时候就需要用到单例模式,单例模式有两种设计:
- 延迟加载(懒汉式)
- 私有构造方法
- 创建本类对象,但不初始化
- 创建静态方法进行初始化对象并返回
- 立即加载(饿汉式)
- 私有构造方法
- 创建本类的对象并初始化(私有的)
- 创建静态方法获取本类对象
下面用代码做个实例:
package com.wzlove.single;
/**
* 延迟加载(懒汉式)
* 1.私有构造方法
* 2.创建本类对象,但不初始化
* 3.创建静态方法进行初始化对象并返回
*
* 优点:
* 使用到类的对象才会加载,不消耗内存
* 缺点:
* 可能会出现线程安全问题,但是可以使用同步代码块消除这个安全问题
* @author WZLOVE
* @create 2018-07-19 10:36
*/
public class DeplayedSingle {
// 私有构造方法
private DeplayedSingle(){}
// 创建本类对象,不初始化
private static DeplayedSingle instance ;
// 静态方法初始化
public static DeplayedSingle getInstance(){
synchronized (DeplayedSingle.class){
if(instance == null){
instance = new DeplayedSingle();
}
}
return instance;
}
}
package com.wzlove.single;
/**
* 立即加载(饿汉式)
* 1.私有构造方法
* 2.创建本类的对象并初始化(私有的)
* 3.创建静态方法获取本类对象
*
* 优点:
* 保证的线程的安全,没有线程安全问题
* 缺点:
* 使用类就会加载,比较消耗内存
* @author WZLOVE
* @create 2018-07-19 10:37
*/
public class ImmediateSingle {
private ImmediateSingle(){}
private static ImmediateSingle instance = new ImmediateSingle();
public static ImmediateSingle getInstance(){
return instance;
}
}
线程池
概述
线程池其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,
无需反复创建线程而消耗过多资源。作用是节省资源,原理是容器.
使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题.如果不使用线程池,
有可能造成系统创建大量同类线程而导致消耗完内存或者"过度切换"的问题.
创建线程池:
- public static ExecutorService newFixedThreadPool(int nThreads) :返回线程池对象。(创建的是有界线
程池,也就是池中的线程个数可以指定最大数量) - public Future<?> submit(Runnable task) :获取线程池中的某一个线程对象,并执行
- Future接口:用来记录线程任务执行完毕后产生的结果。线程池创建与使用。
步骤:
- 使用线程池的工厂类Executors里面提供静态方法newFixedThreadPool生产一个指定线程数量的线程池
- 创建一个类,实现Runnable接口,重写run方法,设置线程任务
- 调用ExecutorService中的方法submit,传递线程任务(实现类),开启线程(前提是线程池中有线程可用),执行run方法
- 调用ExecutorService中的shutdown方法销毁线程池(不建议执行)
补充线程的创建
创建线程的第三种方式(这种方式很少见)
package com.wzlove.executor;
import java.util.ArrayList;
import java.util.concurrent.Callable;
/**
* 线程的第三种创建方法
* Callable有返回值并且可以抛出异常
* @author WZLOVE
* @create 2018-07-18 14:14
*/
public class CallableImpl implements Callable<String> {
private static ArrayList<String> arrayList = new ArrayList<>();
static{
arrayList.add("1");
}
@Override
public String call() throws Exception {
return Thread.currentThread().getName();
}
}
package com.wzlove.executor;
import java.util.concurrent.*;
/**
* 测试线程的第三中创建方式
*
* @author WZLOVE
* @create 2018-07-18 14:14
*/
public class Demo {
public static void main(String[] args) {
// 创建实现Callable的实现类对象
Callable<String> callable = new CallableImpl();
// 创建FutureTask,并传递Callable接口的实现类对象
FutureTask task = new FutureTask(callable);
// 创建线程池对象
// ExecutorService executor = Executors.newSingleThreadExecutor();
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(callable);
// 执行线程
executor.execute(task);
try {
System.out.println(task.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
Lambda表达式
lambda体现的是一种函数式编程的思想, 它强调的是做什么,而不是以什么形式做。
使用前提
- 使用Lambda必须具有接口,且要求接口中有且仅有一个抽象方法。无论是JDK内置的Runnable 、Comparator 接口还是自定义的接口,只有当接口中的抽象方法存在且唯一时,才可以使用Lambda。
- 使用Lambda必须具有上下文推断。也就是方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。
有且仅有一个抽象方法的接口,称为“函数式接口”。
Lambda标准格式
Lambda省去面向对象的条条框框,格式由3个部分组成:
- 一些参数
- 一个箭头
- 一段代码
Lambda表达式的标准格式为:
(参数类型 参数名称) ‐> { 代码语句 }
格式说明:
- 小括号内的语法与传统方法参数列表一致:无参数则留空;多个参数则用逗号分隔。
- -> 是新引入的语法格式,代表指向动作。
- 大括号内的语法与传统方法体要求基本一致。
线程匿名内部类的转化(无参无返回值)
实现Runnable接口的匿名内部类的实现:
public class Demo01Runnable {
public static void main(String[] args) {
// 匿名内部类
Runnable task = new Runnable() {
@Override
public void run() { // 覆盖重写抽象方法
System.out.println("多线程任务执行!");
}
};
new Thread(task).start(); // 启动线程
}
}
代码分析
- Thread 类需要Runnable 接口作为参数,其中的抽象run 方法是用来指定线程任务内容的核心;
- 为了指定run 的方法体,不得不需要Runnable 接口的实现类;
- 为了省去定义一个RunnableImpl 实现类的麻烦,不得不使用匿名内部类;
- 必须覆盖重写抽象run 方法,所以方法名称、方法参数、方法返回值不得不再写一遍,且不能写错;
- 而实际上,似乎只有方法体才是关键所在。
使用Lambda进行简化:
public class Demo01Runnable {
public static void main(String[] args) {
new Thread(()->System.out.println("多线程任务执行!")).start(); // 启动线程
}
}
比较器内部类的转化(有参有返回值)
使用比较器举个例子:
// 创建数组
Integer[] arr = {1,8,3,4,9,2,5};
// 匿名内部类实现数组升序排序
Arrays.sort(arr,new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2) {
return 0;
}
});
// 使用lambda进行数组的升序排序
Arrays.sort(arr,( a, b)->{ return a - b ;});
Lambda表达式的省略规则
在Lambda标准格式的基础上,使用省略写法的规则为:
- 小括号内参数的类型可以省略;
- 如果小括号内有且仅有一个参,则小括号可以省略;
- 如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号。
虽然有省略写法,但是我感觉这个有点灵活,所以不建议省略,因为代码是给别人看的,省略的话感觉别人看起来会有点费劲.
Java之线程池和Lambda表达式的更多相关文章
- Java【线程池、Lambda表达式】
见pdf 等待唤醒机制 wait和notify 第二章 线程池 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低 系统的效率,因为频繁创建线程和销毁 ...
- JavaSE学习笔记(13)---线程池、Lambda表达式
JavaSE学习笔记(13)---线程池.Lambda表达式 1.等待唤醒机制 线程间通信 概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同. 比如:线程A用来生成包子的,线程B用 ...
- 01 语言基础+高级:1-7 异常与多线程_day07 【线程池、Lambda表达式】
day07[线程池.Lambda表达式] 主要内容 等待与唤醒案例 线程池 Lambda表达式 教学目标 -[ ] 能够理解线程通信概念-[ ] 能够理解等待唤醒机制-[ ] 能够描述Java中线程池 ...
- 328 day07线程池、Lambda表达式
day07[线程池.Lambda表达式] 主要内容 等待与唤醒案例 线程池 Lambda表达式 教学目标 -[ ] 能够理解线程通信概念 -[ ] 能够理解等待唤醒机制 -[ ] 能够描述Java中线 ...
- 线程池、Lambda表达式
线程池.Lambda表达式 线程池.Lambda表达式 线程池.Lambda表达式 线程池.Lambda表达式 线程池.Lambda表达式 线程池.Lambda表达式 线程池.Lambda表达式 (正 ...
- 线程池和lambda表达式
线程池1.什么是线程池.一个用来创建和管理线程的容器;2.线程池的作用.提高线程的复用性,降低资源消耗提高线程的响应速度,提高线程的可管理性3.线程的核心思想;线程的复用 4.线程池的创建Execut ...
- Java线程池 与Lambda
七.线程池.Lambda 1.1基本概念: 线程池:其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多的资源. 1.2线程池的好处: ...
- Java 终于在 Java 8 中引入了 Lambda 表达式。也称之为闭包或者匿名函数。
本文首发于 blog.zhaochunqi.com 转载请注明 blog.zhaochunqi.com 根据JSR 335, Java 终于在 Java 8 中引入了 Lambda 表达式.也称之为闭 ...
- 深入理解Java之线程池
原作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本文归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...
随机推荐
- IDEA 2018 最新激活码 License server
IDEA 2018 最新激活码 License server 总会有一个属于适合你的!嘻嘻 http://hb5.s.osidea.cc:1017 http://idea.youbbs.org htt ...
- Spring Data REST PATCH请求远程代码执行漏洞(CVE-2017-8046) 本地复现方法
#1背景 Spring Data REST是Spring Data项目的一部分,可以轻松地在Spring Data存储库之上构建超媒体驱动的REST Web服务. 恶意的PATCH请求使用精心构造 ...
- Scrum立会报告+燃尽图(十二月七日总第三十八次):功能测试
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://git.coding.net/zhang ...
- Visual Studio AI 离线模型训练(window 7)
本篇博客用tensorflow训练自带的数据mnist,参考自博客. 背景: 搭建好AI环境:查看 window 7 64位 准备工作: 在搭建AI环境过程中下载的samples-for-ai不是最新 ...
- 探路者-Beta发布中间产物
版本控制 版本控制报告:http://www.cnblogs.com/linym762/p/7881047.html git地址:https://git.coding.net/clairewyd/to ...
- Team Member Introduction and Division of Work
Team leader Name:宋天舒 Student Number:12061166 Interested In: Information safety. Responsible For: Des ...
- BugPhobia发布篇章:学霸在线系统正式发布
Alpha阶段的服务器部署和移植工作最终完成,http://10.2.26.67/,期待您的访问~ 首先,请允许bugphobia团队对您的访问给予感谢以及诚恳的致歉.受服务器端的硬件限制,目前学霸在 ...
- 用java构造一个带层次的文件目录遍历器
import java.util.List; import java.io.File; import java.util.ArrayList; public class IteratorUtil { ...
- Struct2笔记②--完善登陆代码
上节课的代码 写完整 登陆成功在页面上显示用户名和密码: username:${requestScope.username }<br> password:${requestScope. ...
- POJ 2104 K-th Number 主席树(区间第k大)
题目链接: http://poj.org/problem?id=2104 K-th Number Time Limit: 20000MSMemory Limit: 65536K 问题描述 You ar ...