线程池和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. socket 编程 : shutdown vs close

    TCP/IP 四次挥手 首先作者先描述一下TCP/IP 协议中四次挥手的过程,如果对此已经熟悉的读者可以跳过本节. 四次挥手 这是一个很经典的示例图,众所周知tcp socket 在一个生命周期中有很 ...

  2. QRCode 二维码

    一.生成二维码 1.二维码就是绘制成黑白相间的图片,所谓的黑白相间就是代表0和1 ,二维码大约可以容纳500多个中文,所以用途之广显而易见. 所需的jar包  http://pan.baidu.com ...

  3. AlexNet论文翻译-ImageNet Classification with Deep Convolutional Neural Networks

    ImageNet Classification with Deep Convolutional Neural Networks 深度卷积神经网络的ImageNet分类 Alex Krizhevsky ...

  4. tensorflow-gpu与CUDA、CUDNN的版本问题

    折腾了将近两天的时间,终于搞好了,感觉把所有的坑都踩过了一遍.....泪牛满面 1.先安装CUDA,并安装,尽量不要下载最新版本的,坑,本机可以下载最新本10.0版本,但与CUDNN和tensorfl ...

  5. 10款常见MySQL高可用方案选型解读

    一.概述 我们在考虑MySQL数据库的高可用架构时,主要考虑如下几方面: 如果数据库发生了宕机或者意外中断等故障,能尽快恢复数据库的可用性,尽可能的减少停机时间,保证业务不会因为数据库的故障而中断. ...

  6. c++第七次作业____最后的总结

    先言: 在这过程中学到: 第二次作业Github的使用 第四次作业计算器的计算 ps:表达式处理以及计算 第五次作业文件的处理问题 第六次作业界面的设计 总结: 1.这学期的计算器,做的有点匆忙,偶尔 ...

  7. ubuntu16.04+cuda8.0+caffe

    =========== 如果出现nvidia-smi failed to communicate with nvidia driver,循环登录情况,则: sudo apt-get remove -- ...

  8. ssh框架配置数据源 数据库连接没有正常释放

    通过多天的改bug 对数据源这个东西了解多了..    我发现 spring+hibernate下  申请数据库连接是在一个action方法内  也就是说  action 里面有三个 service方 ...

  9. Web应用程序的基本安全实践

    创建安全Web应用程序的主题非常广泛.它需要研究以了解安全漏洞.您还需要熟悉Windows..NET框架和ASP.NET的安全设施.最后,有必要了解如何使用这些安全特性来对付威胁. 即使您没有安全方面 ...

  10. Navicat Premium 连接Oracle 数据库

    昨天开始工作的时候听同事说:Navicat可以连各种数据库,包括Oracle,头一次听说!!!很是尴尬.现在记录一下怎么用Navicat连接Oracle.最重要的是,Navicat只支持32的Orac ...