线程池和lambda表达式

学习线程池和lambda表达式的理解

补充一个知识点(单例设计模式)

在多线程中,我们只需要一个任务类,为了防止创建多个任务类,这个时候就需要用到单例模式,单例模式有两种设计:

  1. 延迟加载(懒汉式)

    • 私有构造方法
    • 创建本类对象,但不初始化
    • 创建静态方法进行初始化对象并返回
  2. 立即加载(饿汉式)
    • 私有构造方法
    • 创建本类的对象并初始化(私有的)
    • 创建静态方法获取本类对象

下面用代码做个实例:

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标准格式的基础上,使用省略写法的规则为:

  1. 小括号内参数的类型可以省略;
  2. 如果小括号内有且仅有一个参,则小括号可以省略;
  3. 如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号。

虽然有省略写法,但是我感觉这个有点灵活,所以不建议省略,因为代码是给别人看的,省略的话感觉别人看起来会有点费劲.

Java之线程池和Lambda表达式的更多相关文章

  1. Java【线程池、Lambda表达式】

    见pdf 等待唤醒机制 wait和notify 第二章 线程池 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低 系统的效率,因为频繁创建线程和销毁 ...

  2. JavaSE学习笔记(13)---线程池、Lambda表达式

    JavaSE学习笔记(13)---线程池.Lambda表达式 1.等待唤醒机制 线程间通信 概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同. 比如:线程A用来生成包子的,线程B用 ...

  3. 01 语言基础+高级:1-7 异常与多线程_day07 【线程池、Lambda表达式】

    day07[线程池.Lambda表达式] 主要内容 等待与唤醒案例 线程池 Lambda表达式 教学目标 -[ ] 能够理解线程通信概念-[ ] 能够理解等待唤醒机制-[ ] 能够描述Java中线程池 ...

  4. 328 day07线程池、Lambda表达式

    day07[线程池.Lambda表达式] 主要内容 等待与唤醒案例 线程池 Lambda表达式 教学目标 -[ ] 能够理解线程通信概念 -[ ] 能够理解等待唤醒机制 -[ ] 能够描述Java中线 ...

  5. 线程池、Lambda表达式

    线程池.Lambda表达式 线程池.Lambda表达式 线程池.Lambda表达式 线程池.Lambda表达式 线程池.Lambda表达式 线程池.Lambda表达式 线程池.Lambda表达式 (正 ...

  6. 线程池和lambda表达式

    线程池1.什么是线程池.一个用来创建和管理线程的容器;2.线程池的作用.提高线程的复用性,降低资源消耗提高线程的响应速度,提高线程的可管理性3.线程的核心思想;线程的复用 4.线程池的创建Execut ...

  7. Java线程池 与Lambda

    七.线程池.Lambda 1.1基本概念: ​ 线程池:其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多的资源. 1.2线程池的好处: ...

  8. Java 终于在 Java 8 中引入了 Lambda 表达式。也称之为闭包或者匿名函数。

    本文首发于 blog.zhaochunqi.com 转载请注明 blog.zhaochunqi.com 根据JSR 335, Java 终于在 Java 8 中引入了 Lambda 表达式.也称之为闭 ...

  9. 深入理解Java之线程池

    原作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本文归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...

随机推荐

  1. 关于MySql数据库主键及索引的区别

    一.什么是索引?索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里 ...

  2. 1.Python3.6环境部署

    标题:Python3.6环境部署文档 作者:刘耀 内容 Linux部署Python3.6环境 Mac部署Python3.6环境 Window10部署Python3.6环境 Pycharm安装 1. L ...

  3. iframe子页面position的fixed

    前言: 首先说一说我昨天天的苦逼经历.中午吃饭时一同事跟我说,他做的项目嵌套iframe后,子页面的position设置fixed失效了. 经过反复询问,得知他用了两层iframe,再加上最外的父页面 ...

  4. Python List Comprehension

    (一)使用List Comprehension的好处 在了解Python的List Comprehension之前,我们习惯使用for循环创建列表,比如下面的例子: numbers = range(1 ...

  5. scrapy有用的(代理,user-agent,随机延迟等)

    代理 方法一(待测试) 见scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware import os # 设置相应的代理用户名密码,主机和 ...

  6. 【转】git乱码解决方案汇总

    git乱码解决方案汇 2012-11-04更新:官方的“终极”解决方案:msysGit1.7.10开始使用UTF-8编码保存文件名. 2011-10-24更新: 从一篇链接到本篇文章的文章(我对这篇文 ...

  7. 看oracle的sid

    ps -ef|grep pmon 可以从进程名字里看到 也可以通过 sqlplus / as sysdbashow parameter instance_name

  8. 互评Beta版本——Thunder组爱阅app(探路者团队测评)

    基于NABCD评论作品,及改进建议 每个小组评论其他小组beta发布的作品. 1.根据(不限于)NABCD评论作品的选题;   N(Need,需求):在Beta中加入了书友QQ群,以及反馈建议,更好的 ...

  9. Scrum Meeting 10.25

    成员 已完成任务 下一阶段任务 用时 徐越 阅读前端代码中和通信相关的部分 学习服务器配置 4h 赵庶宏 阅读前端代码中和通信相关的部分 学习服务器配置 4h 薄霖 继续做UI开发 界面优化 4h 武 ...

  10. First scrum meeting report - 151017

    提要 今天开会主要是讨论一下北航MOOC客户端的具体要求和每个人的大致分工.会议后来还简单商讨了一下我们app的大致界面框架. 会议地点:大运村KFC 会议时间:2015年10月17日,15:00-1 ...