标签:lov 抽象 启动 cep 异常 步骤 over task submit
学习线程池和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;
}
}
线程池其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,
无需反复创建线程而消耗过多资源。作用是节省资源,原理是容器.
使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题.如果不使用线程池,
有可能造成系统创建大量同类线程而导致消耗完内存或者"过度切换"的问题.
创建线程池:
步骤:
创建线程的第三种方式(这种方式很少见)
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省去面向对象的条条框框,格式由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标准格式的基础上,使用省略写法的规则为:
虽然有省略写法,但是我感觉这个有点灵活,所以不建议省略,因为代码是给别人看的,省略的话感觉别人看起来会有点费劲.
标签:lov 抽象 启动 cep 异常 步骤 over task submit
原文地址:https://www.cnblogs.com/wadmwz/p/9337903.html