it-swarm.com.de

Faden mit Lambda-Ausdruck

Ich habe einen Fehler in Zeile 42 und 43: Thread t1=new Thread(()->prod.test());, Thread t2=new Thread(()->cons.test()); Unbehandelter Ausnahmetyp InterruptedException . Wenn ich versuche, das Problem zu beheben, wird der Trycatch mit einem catch Exception erstellt. Es wird derselbe Fehler angezeigt und es wird versucht, den Fehler auf dieselbe Weise zu beheben, indem er fortfährt, es mit Trycatch zu umgeben.

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

}
12
T4l0n

Sie haben eine funktionale Schnittstelle Predicate erstellt, deren Methode so konfiguriert ist, dass sie eine InterruptedException auslöst, bei der es sich um eine geprüfte Ausnahme handelt. Sie rufen jedoch test() im Körper eines Lambda-Ausdrucks als Parameter für den Thread-Konstruktor, der eine Runnable verwendet an, dessen run()-Methode nicht zum Ausgeben geprüfter Ausnahmen deklariert ist . Daher tritt ein Compiler-Fehler auf, da die Ausnahme nicht im Hauptteil abgefangen wird.

Im Übrigen kann es verwirrend sein, Ihre eigene Schnittstelle Predicate zu nennen, weil eingebaute Funktionsschnittstelle Java.util.function.Predicate ist, deren Funktionsmethode eine boolean zurückgibt.

Da run() keine Exception werfen kann, müssen Sie die catch-Ausnahme__ behandeln und damit umgehen. Sie können die Ausnahme und ihre Stack-Ablaufverfolgung protokollieren. Sie können die Ausnahme in eine RuntimeException einschließen. In beiden Fällen kann der Code durch das Abfangen der geprüften Ausnahme kompiliert werden. Beispiel:

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

Wie @ rgettman sagt, ist der Name Predicate unglücklich ... Wie auch immer, Sie könnten default-Methoden in Java nutzen:

interface PredicateButPleaseChangeMyName {

    void test() throws InterruptedException;

    default void tryTest() {
       try {
          this.test();
       } catch (InterruptedException e) {
          // handle e (log or wrap in a RuntimeException)
       }
    }
}

Dann erstellen Sie einfach in Ihrer Hauptmethode die Threads, indem Sie die Standardmethode tryTest() aufrufen:

Thread t1 = new Thread(() -> prod.tryTest());
Thread t2 = new Thread(() -> cons.tryTest());

Wenn Sie nur eine Methode ohne Argumente ausführen möchten, können Sie das Lambda durch eine Methodenreferenz ersetzen.

Zum Beispiel:

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

kann prägnanter ausgedrückt werden als 

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