juc下的方法
一、CountDownLatch类
是一个Java的并发工具类,用于使一个线程等待其他线程完成各自的工作。其主要用法如下:
-
创建一个CountDownLatch实例,指定初始计数器的值。
CountDownLatch countDownLatch = new CountDownLatch(3);
-
在需要等待的线程中调用await()方法,该方法会阻塞当前线程,直到计数器减到0。
countDownLatch.await();
-
在其他线程中,每次完成一项工作后,调用countDown()方法来减少计数器的值。
countDownLatch.countDown();
当所有线程都完成了各自的工作后,计数器减为0,此时等待的线程会从await()方法返回,继续执行后续代码。
以下是一个简单的示例代码:
public class CountDownLatchExample { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(3); Thread thread1 = new Thread(() -> { System.out.println("Thread 1 started"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread 1 finished"); countDownLatch.countDown(); }); Thread thread2 = new Thread(() -> { System.out.println("Thread 2 started"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread 2 finished"); countDownLatch.countDown(); }); Thread thread3 = new Thread(() -> { System.out.println("Thread 3 started"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread 3 finished"); countDownLatch.countDown(); }); thread1.start(); thread2.start(); thread3.start(); countDownLatch.await(); // 等待所有线程完成工作后返回继续执行后续代码... } }
补充1:
Lambda表达式是Java 8引入的一种新特性,用于简洁地表示某些匿名函数(即没有名称的函数)。
(参数列表) -> { 函数体 }
参数列表可以是零个、一个或多个参数,参数类型由编译器自动推断或显式声明。函数体包含一条或多条语句,如果只有一条语句,则大括号可以省略,且表达式的返回值类型要与匿名函数的返回类型相同。
例子:
(int x, int y)-> x + y
表示接受两个整数参数x和y,并返回它们的和。可以将其应用于一些需要接受两个参数并返回结果的函数,例如:
Function<Integer, Integer, Integer> add = (int x, int y) -> x + y; int result = add.apply(2, 3); // 返回5
在这个例子中,我们定义了一个名为add的函数,它接受两个整数参数并返回它们的和。然后我们使用Lambda表达式来定义这个函数的行为,并将其应用于apply方法。
补充2:
函数接口:是只有一个抽象方法的接口。在Java中,函数接口是使用@FunctionalInterface
注解来标记的。它们允许我们以简洁的方式编写匿名函数。
主要用途是用于Lambda表达式和方法引用。
Java库提供了一些常用的函数接口,如Runnable(定义线程)
、Callable(任务)
、Comparator(排序内容)、Consumer
、Supplier
、Function(规则)
、Predicate(测试T/F)等
import java.util.function.Function; public class FunctionInterfaceExample { public static void main(String[] args) { Function<String, Integer> toUpperCase = str -> str.length(); //将Lambda表达式赋值给Function
接口的实例变量 int length = toUpperCase.apply("Hello"); //我们使用Lambda表达式来实例化该接口,并调用apply()
方法来调用这个函数并输出结果。 System.out.println("Length: " + length); } }
使用Comparator
接口对一个Person
对象的列表进行排序:
public class Person { private String name; private int age; // 构造函数、getter和setter方法省略... } //然后,我们创建一个Person对象的列表,并使用Collections.sort()方法对其进行排序: import java.util.*; public class ComparatorExample { public static void main(String[] args) { List<Person> people = new ArrayList<>(); people.add(new Person("Alice", 25)); people.add(new Person("Bob", 20)); people.add(new Person("Charlie", 30)); // 使用匿名内部类实现Comparator接口 Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { // 按年龄升序排序 return Integer.compare(p1.getAge(), p2.getAge()); } }); // 打印排序后的列表 for (Person person : people) { System.out.println(person.getName() + " " + person.getAge()); } } }
在上面的例子中,我们使用了一个匿名内部类来实现了Comparator
接口,并重写了compare
方法,按照年龄升序对Person
对象进行排序。最后,我们打印了排序后的列表。
另外,你也可以使用lambda表达式来简化代码:
Collections.sort(people, (p1, p2) -> Integer.compare(p1.getAge(), p2.getAge()));
Collections.sort()方法对集合进行排序时,可以传递一个比较器(Comparator)函数接口作为参数,来定义排序的规则。同样地,在映射操作中,可以使用Function接口作为参数来定义映射的规则。
Predicate接口接受一个参数并返回一个布尔值,因此它可以用作谓词,用于测试某个条件是否为真。
要使用Predicate函数接口,你需要实现它的test
方法。这个方法接受一个参数,并返回一个布尔值。你可以使用lambda表达式或方法引用来实现这个方法。
//表达式用法 Predicate<Integer> isEven = n -> n % 2 == 0; boolean result = isEven.test(4); System.out.println(result); // 输出 true //方法引用用法 Predicate<Integer> isEven = Integer::valueOf -> value % 2 == 0; boolean result = isEven.test(4); System.out.println(result); // 输出 true
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)