具有 Lambda 表达式的线程

我在第42行和第43行有一个错误:,未处理的异常类型中断异常。如果我尝试快速修复它将创建带有捕获异常的try catch,它将具有相同的错误,并将尝试以相同的方式修复它,并继续用try catch包围它。Thread t1=new Thread(()->prod.test());Thread t2=new Thread(()->cons.test());

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());
    }

}

答案 1

您已经创建了一个函数接口,其方法被声明为抛出 一个 ,这是一个已检查的异常。但是,您可以在 lambda 表达式的主体中作为参数调用采用 RunnableThread 构造函数,其 run() 方法未声明为引发任何选中的异常。因此,由于正文中未捕获异常,因此会发生编译器错误。PredicateInterruptedExceptiontest()

顺便说一句,命名自己的接口可能会令人困惑,因为内置的功能接口java.util.function.Predicate,其函数方法返回一个。Predicateboolean

因为不能抛出一个,所以必须对异常进行处理。您可以记录异常及其堆栈跟踪。您可以将异常包装在 .无论哪种方式,捕获已检查的异常都将允许代码进行编译。例:run()ExceptioncatchRuntimeException

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);
    }
});

答案 2

如果您打算仅运行没有参数的单个方法,则可以将 lambda 替换为方法引用。

例如:

Thread t = new Thread(() -> {
        foo();
    });

可以更简洁地表示为

Thread t = new Thread(this::foo);

推荐