使用 Lambda 表达式的线程
Thread with Lambda expression
我在第 42 和 43 行有一个错误:Thread t1=new Thread(()->prod.test());
,Thread t2=new Thread(()->cons.test());
未处理的异常类型 InterruptedException。如果我尝试快速修复,它会创建带有 catch Exception 的 try catch,它会出现相同的错误,并会尝试以相同的方式修复它,继续用 try catch 包围它。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
interface Predicate {
public void test() throws InterruptedException;
}
class MyClass {
int num = 0;
Lock lock = new ReentrantLock();
public void produce() throws InterruptedException {
lock.lock();
for (int i = 0; i < 1000; i++) {
num++;
Thread.sleep(1);
}
lock.unlock();
}
public void consume() throws InterruptedException {
lock.lock();
for (int i = 0; i < 1000; i++) {
num--;
Thread.sleep(1);
}
lock.unlock();
}
public int getNum() {
return num;
}
}
public class Main00 {
public static void main(String[] args) throws InterruptedException {
MyClass c = new MyClass();
Predicate prod = c::produce;
Predicate cons = c::consume;
Thread t1 = new Thread(() -> prod.test());
Thread t2 = new Thread(() -> cons.test());
long start = System.currentTimeMillis();
t1.start();
t2.start();
t1.join();
t2.join();
long end = System.currentTimeMillis();
System.out.println("time taken " + (end - start) + " num = "
+ c.getNum());
}
}
您已经创建了一个功能接口 Predicate
,其方法被声明为抛出一个 InterruptedException
,这是一个已检查的异常。但是,您在 lambda 表达式的主体中调用 test()
作为 the Thread
constructor that takes a Runnable
, whose run()
method is not declared to throw any checked exceptions 的参数。因此,由于没有在body中捕获到异常,所以出现了编译错误。
顺便说一下,将您自己的接口命名为 Predicate
可能会造成混淆,因为 built-in functional interface java.util.function.Predicate
的功能方法 returns 和 boolean
.
因为run()
不能抛出Exception
,你必须catch
异常并处理它。您可能会记录异常及其堆栈跟踪。您可以将异常包装在 RuntimeException
中。无论哪种方式,捕获已检查的异常都将允许代码编译。示例:
Thread t1 = new Thread(() -> {
try {
prod.test();
} catch (InterruptedException e) {
// handle: log or throw in a wrapped RuntimeException
throw new RuntimeException("InterruptedException caught in lambda", e);
}
});
正如@rgettman 所说,Predicate
这个名字让人不高兴...无论如何,您可以利用 Java:
中的 default
方法
interface PredicateButPleaseChangeMyName {
void test() throws InterruptedException;
default void tryTest() {
try {
this.test();
} catch (InterruptedException e) {
// handle e (log or wrap in a RuntimeException)
}
}
}
然后,在您的 main 方法中,通过调用默认 tryTest()
方法简单地创建线程:
Thread t1 = new Thread(() -> prod.tryTest());
Thread t2 = new Thread(() -> cons.tryTest());
如果您打算 运行 只使用一个没有参数的方法,您可以用方法引用替换 lambda。
例如:
Thread t = new Thread(() -> {
foo();
});
可以更简洁地表示为
Thread t = new Thread(this::foo);
我在第 42 和 43 行有一个错误:Thread t1=new Thread(()->prod.test());
,Thread t2=new Thread(()->cons.test());
未处理的异常类型 InterruptedException。如果我尝试快速修复,它会创建带有 catch Exception 的 try catch,它会出现相同的错误,并会尝试以相同的方式修复它,继续用 try catch 包围它。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
interface Predicate {
public void test() throws InterruptedException;
}
class MyClass {
int num = 0;
Lock lock = new ReentrantLock();
public void produce() throws InterruptedException {
lock.lock();
for (int i = 0; i < 1000; i++) {
num++;
Thread.sleep(1);
}
lock.unlock();
}
public void consume() throws InterruptedException {
lock.lock();
for (int i = 0; i < 1000; i++) {
num--;
Thread.sleep(1);
}
lock.unlock();
}
public int getNum() {
return num;
}
}
public class Main00 {
public static void main(String[] args) throws InterruptedException {
MyClass c = new MyClass();
Predicate prod = c::produce;
Predicate cons = c::consume;
Thread t1 = new Thread(() -> prod.test());
Thread t2 = new Thread(() -> cons.test());
long start = System.currentTimeMillis();
t1.start();
t2.start();
t1.join();
t2.join();
long end = System.currentTimeMillis();
System.out.println("time taken " + (end - start) + " num = "
+ c.getNum());
}
}
您已经创建了一个功能接口 Predicate
,其方法被声明为抛出一个 InterruptedException
,这是一个已检查的异常。但是,您在 lambda 表达式的主体中调用 test()
作为 the Thread
constructor that takes a Runnable
, whose run()
method is not declared to throw any checked exceptions 的参数。因此,由于没有在body中捕获到异常,所以出现了编译错误。
顺便说一下,将您自己的接口命名为 Predicate
可能会造成混淆,因为 built-in functional interface java.util.function.Predicate
的功能方法 returns 和 boolean
.
因为run()
不能抛出Exception
,你必须catch
异常并处理它。您可能会记录异常及其堆栈跟踪。您可以将异常包装在 RuntimeException
中。无论哪种方式,捕获已检查的异常都将允许代码编译。示例:
Thread t1 = new Thread(() -> {
try {
prod.test();
} catch (InterruptedException e) {
// handle: log or throw in a wrapped RuntimeException
throw new RuntimeException("InterruptedException caught in lambda", e);
}
});
正如@rgettman 所说,Predicate
这个名字让人不高兴...无论如何,您可以利用 Java:
default
方法
interface PredicateButPleaseChangeMyName {
void test() throws InterruptedException;
default void tryTest() {
try {
this.test();
} catch (InterruptedException e) {
// handle e (log or wrap in a RuntimeException)
}
}
}
然后,在您的 main 方法中,通过调用默认 tryTest()
方法简单地创建线程:
Thread t1 = new Thread(() -> prod.tryTest());
Thread t2 = new Thread(() -> cons.tryTest());
如果您打算 运行 只使用一个没有参数的方法,您可以用方法引用替换 lambda。
例如:
Thread t = new Thread(() -> {
foo();
});
可以更简洁地表示为
Thread t = new Thread(this::foo);