Java学习第二十四天知识点(线程池、1.8新特性)
线程池:
1.概念:其实就是⼀个容纳多个线程的容器,其中的线程可以反复使⽤,省去了频繁创建线
程对象的操作,⽆需反复创建线程⽽消耗过多资源
2.好处:节约内容,提高效率
3.创建方式: 使用Executors 工厂类中的静态方法
1).newCachedThreadPool() - 根据须需要创建线程池
2).newFixedThreadPool(int nThreads) - 创建固定数量的线程池
3).newScheduledThreadPool(int corePoolSize) - 创建周期性执行的线程池
4).newSingleThreadExecutor() - 创建单个线程的线程池
部分创建方式测试:
public static void main(String[] args) {
//根据需求创建线程数量
ExecutorService nctp =Executors.newCachedThreadPool();
//线程池里三个重复利用的线程,多出的任务排队,等待执行完成
ExecutorService nftp = Executors.newFixedThreadPool(3);
//Runnable myRunable=new Handler();
Runnable run=new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
try {System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread = new Thread(run);
//没有返回值
//ex.execute(run);
//有返回值
/* nftp.submit(run);
nftp.submit(run);
nftp.submit(run);
nftp.submit(run);
nftp.submit(run);
System.out.println(nftp.submit(run));//java.util.concurrent.FutureTask@3aa9e816
nftp.shutdown();*/
nctp.submit(run);
nctp.submit(run);
nctp.submit(run);
nctp.submit(run);
nctp.submit(run);
nctp.shutdown();
}
4.Callable接口 -> 为了取代 Runnable
1).Callable不能在Thread类中使用,只能在线程池中使用
2).注意:
a.submit() 会有返回值,Future
b.使用 get()接收call()的返回值
可能会遇到阻塞,需要一直等待
c.使用get(long, TimeUnit) -> 超时等待
Callable接口测试:
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<Date> cal = new Callable<>() {
@Override
public Date call() throws Exception {
for (int i = 0; i < 6; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
Thread.sleep(3000);
return new Date();
}
};
ExecutorService es = Executors.newFixedThreadPool(3);
Future<Date> submit = es.submit(cal);
//Date date = submit.get();
//如果运行超过两秒,那么打印出超时
try {
submit.get(2, TimeUnit.SECONDS);
} catch (TimeoutException e) {
System.out.println("超时");
}
//System.out.println(date);
System.out.println("后续执行开始");
es.shutdown();
}
}
属性集: Properties
1).特点:
a.Properties是以键值对的方式进行存储
b.但是键值对仅支持String类型的属性映射
2)常用方法:
a. void getProperty() -> 通过key获取value值
void setProperty() -> 了解
b.加载属性集(配置文件)
void load(Reader)
void load(InputStream)
c.获取路径 - 可以直接放在src下
方式一(得到的是String类型路径):
xx.class.getClassLoader().getResource("相对路径").getPath();
方式二:
xx.class.getClassLoader().getResourceAsStream("相对路径");
如下代码片段测试可得到更直观结果:
String path=PropertyDemo.class.getClassLoader().getResource("config.properties").getPath();
//p.load(new InputStreamReader(new FileInputStream(path)));
p.load(new FileInputStream(path));
System.out.println(path);
InputStream rs = PropertyDemo.class.getClassLoader().getResourceAsStream("config.properties");
p.load(rs);
System.out.println(rs);
JDK1.8的新特性
Lambda表达式:函数式编程思想(c++ c#)
1.语法结构:
(参数列表) -> {逻辑代码}
1). (参数列表): 表示要重写的抽象方法的参数列表
2). ->: 表示固定语法(固定指向),指向/传递的意思
3). {逻辑代码}: 要重写的方法代码
4). 优化写法 - 既可推导可省略
a. ()中参数类型,可以省略
如果有多个参数类型,每个参数类型都要一起省略
b. {}中如果代码只有一行,不论这个方法有没有返回值,那么【 {} return ;】都可以省略,而且必须一起省略
c. ()中如果只有一个参数,()可以省略,和类型一起省略
()中如果没有参数,()必须写
使用前提:
1.实现一个接口
2.接口中只能有一个抽象方法
3.接口是作为方法的参数使用
常用的函数式接口
supplier:生产者
抽象方法: T get()
作用: 生产对象
consumer:消费者
抽象方法: void accept(T t)
默认方法: andThen(Consumer) - 将两个消费组合在一起使用
作用: 使用对象
predicate function
新特性优化写法:
public static void main(String[] args) {
Runnable run = new Runnable() {
@Override
public void run() {
System.out.println(1);
}
};
//优化
//因为run里面没有参数所可以这样写
Runnable run1 = ()-> { System.out.println(1); };
//实际上应该这样
Runnable run2 = ()-> System.out.println(1);
List<Integer> list = List.of(9,1, 2, 3);
list = new ArrayList<>(list);
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
//Lambda优化去掉new Comparator<Integer>()
// @Override public int compare {}
Collections.sort(list,(Integer o1, Integer o2) ->{ return o2-o1; });
//再去掉参数类型
Collections.sort(list,(o1,o2) ->{ return o2-o1; });
//只有一行代码的情况 下大括号+;+return 这个组合也可以删
Collections.sort(list,(o1,o2) -> o2-o1 );
}