线程池
属性集
lambda表达式
线程池:
其实就是⼀个容纳多个线程的容器,其中的线程可以反复使⽤,省去了频繁创建线程对象的 操作,⽆需反复创建线程⽽消耗过多资源。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SvSbUr6j-1658148169889)(C:\Users\13460\AppData\Roaming\Typora\typora-user-images\1658114828159.png)]
合理利用线程池能够带来的好处:
1、降低 资源的消耗。减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可以执行多个任务。
2、提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行
3、提高线程的可管理性。可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后司机)。
线程池的使用:
Executors 类中有个创建线程池的⽅法如下: public static ExecutorService newFixedThreadPool(int nThreads) :返回线程池对象。 (创建的是有界线程池,也就是池中的线程个数可以指定最⼤数量) 。
获取到了⼀个线程池 ExecutorService 对象,那么怎么使⽤呢,在这⾥定义了⼀个使⽤线程池对象的⽅法如 下: public Future submit(Runnable task) :获取线程池中的某⼀个线程对象,并执⾏ 。
使用线程池中线程对象的步骤:
-
创建线程池对象。
-
创建Runnable接⼝⼦类对象。(task)
-
提交Runnable接⼝⼦类对象。(take task)
-
关闭线程池(⼀般不做)。
实例:
package Demo;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo7 {
public static class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("苹果拿来");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("给你:"+ Thread.currentThread().getName());
System.out.println("吃完了");
}
}
public static void main(String[] args) {
// 创建线程池对象
ExecutorService service = Executors.newFixedThreadPool(2);
//创建Runnable实例对象
MyRunnable r = new MyRunnable();
//自己创建线程对象的方式
// Thread t = new Thread();
//调用run()
// t.start();
// 从线程池中获取线程对象,然后调⽤MyRunnable中的run()
service.submit(r);
// 再获取个线程对象,调⽤MyRunnable中的run()
service.submit(r);
service.submit(r);
// 注意:submit⽅法调⽤结束后,程序并不终⽌,是因为线程池控制了线程的关闭。
// 将使⽤完的线程⼜归还到了线程池中
// 关闭线程池
service.shutdown();
}
}
属性集:
package b_properties;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
public class Demo1 {
public static void main(String[] args) throws IOException {
// 1.创建属性集对象
Properties props = new Properties();
// 2.从文件中加载属性集(文件内容->读到程序中)
// 配置文件路径通常不会改变 -> 随着工程
// key-value
props.load(new FileReader("config.properties"));
// 最终要使用的是value部分
String path = props.getProperty("filepath");
props.setProperty("key", "value");
// 3.将内容从程序中 存储到 属性集文件中
System.out.println(path);
}
}
package b_properties;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class Demo2 {
public static void main(String[] args) throws IOException {
// 1.创建属性集对象
Properties props = new Properties();
// 步骤2.设置属性集内容
int age = 18;
props.setProperty("age", age + "");
props.setProperty("name", "李四");
// 3.将内容从程序中 存储到 属性集文件中
props.store(new FileWriter("config.properties"), "文件的注释,可以是空白的字符");
}
}
package b_properties;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class Demo3 {
public static void main(String[] args) throws IOException {
// 1.创建属性集对象
Properties props = new Properties();
// 2.加载文件中的属性集
props.load(new FileReader("config.properties"));
// 步骤2.设置属性集内容
props.setProperty("sex", "男");
props.setProperty("salary", "6000");
// 3.将内容从程序中 存储到 属性集文件中
props.store(new FileWriter("config.properties"), "文件的注释,可以是空白的字符");
}
}
package b_properties;
import java.io.*;
import java.net.URL;
import java.util.Properties;
public class Demo4 {
public static void main(String[] args) throws IOException {
// 获得类Demo4所在目录中的资源 -> [b_properties]
String resourcePath = Demo4.class.getResource(
"config.txt").getPath();
System.out.println("resource: " + resourcePath);
new FileReader(resourcePath);
// 获得类Demo4所在工程(src)中的资源 -> src/config.properties ../../
String resourcePath1 = Demo4.class.getResource(
"../config.properties").getPath();
System.out.println("resource1: " + resourcePath1);
new FileReader(resourcePath1);
// 获得Demo4类所在工程的资源 getClassLoader()
String path3 = Demo4.class.getClassLoader()
.getResource("config.properties").getPath();
System.out.println("path3: " + path3);
// 1.创建属性集对象
Properties props = new Properties();
// 2.加载文件中的属性集
props.load(new InputStreamReader(new FileInputStream("20220718/src/config.properties")));
String name = props.getProperty("salary");
System.out.println(name);
props.setProperty("中文", "测试");
// 字符流写入, 使用默认字符集 - UTF-8
// props.store(new FileWriter("config.properties"), "注释");
// 字节流写入, 会将中文转成 ASCII 码, 写入 -> 使用GBK/UTF-8 读出来的都是正常中文
props.store(new FileOutputStream("config.properties"), "注释");
}
}
Lambda表达式:
(JAVA8语法)
Lambda的语法⾮常简洁,完全没有⾯向对象复杂的束缚。但是使⽤时有⼏个问题需要特别注意:
- 使⽤Lambda必须具有接⼝,且要求接⼝中有且仅有⼀个抽象⽅法。 ⽆论是JDK内置的 Runnable 、 Comparator 接⼝还是⾃定义的接⼝,只有当接⼝中的抽象⽅法存在 且唯⼀时,才可以使⽤Lambda。
- 使⽤Lambda必须具有上下⽂推断。 也就是⽅法的参数或局部变量类型必须为Lambda对应的接⼝类型,才能使⽤Lambda作为该接⼝的 实例。
Lambda省去⾯向对象的条条框框,格式由3个部分组成:
⼀些参数 ⼀个箭头 ⼀段代码
() -> {}
格式说明:
⼩括号内的语法与传统⽅法参数列表⼀致:⽆参数则留空;多个参数则⽤逗号分隔。
-> 是新引⼊的语法格式,代表指向动作。
⼤括号内的语法与传统⽅法体要求基本⼀致。
实例:
package Demo;
import java.util.Arrays;
import java.util.Comparator;
public class Demo6 {
public static void m1(ko ko1){
int result = ko1.factorial(5);
System.out.println(result);
}
public static void main(String[] args) {
//例一:
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
}
});
/*
1、能确定传的参数是Runnable类型
2、能确定实现的方法是run方法
*/
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
});
//例二:
Integer [] arr = {1,23,2,5};
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
//1、匿名内部类简化成lambda表达式
Arrays.sort(arr,(Integer o1, Integer o2)->{return o2-o1;});
//2、如果方法有参数,参数类型也可以省略
Arrays.sort(arr,(o1,o2)->{return o2-o1;});
//3、如果方法体中只有一句话,不论方法中需不需要
/*
返回值return可以省略
;可以省略
{}可以省略
ps:要省三者一起省
*/
Arrays.sort(arr,(o1,o2)->o2-o1);
//例三:
//常规写法
m1(new ko() {
@Override
public int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}
});
//1、简化成lambda表达式
m1((int n) -> {
int result = 1;
for (int i = 1; i <= n ; i++) {
result *= 1;
}
return result;
});
//2、第二次简化
m1((n) -> {
int result = 1;
for (int i = 1; i <= n ; i++) {
result *= 1;
}
return result;
});
//3、第三次简化 方法参数只有一个,可以省略()
m1(n ->{
int result = 1;
for (int i = 1; i <= n ; i++) {
result *= 1;
}
return result;
});
}
public interface ko{
int factorial(int n);
}
}
return result;
});
//3、第三次简化 方法参数只有一个,可以省略()
m1(n ->{
int result = 1;
for (int i = 1; i <= n ; i++) {
result *= 1;
}
return result;
});
}
public interface ko{
int factorial(int n);
}
}