Masalah Runnable

Sampeyan wis kenal karo antarmuka Runnable lan kelas Utas sing ngetrapake. Ayo elinga kaya apa antarmuka iki:


public interface Runnable {
	public abstract void run();
}

Elinga yen jinis bali metode run ora sah . Nanging kepiye yen kita butuh benang kanggo ngasilake sawetara asil karyane ing wangun nomer, senar, utawa obyek liyane? Banjur kita kudu nggawe workaround. Kaya iki:


public class Fibonacci implements Runnable {
 
 
 
	private final int index;
 
	private int result;
 
 
 
	public Fibonacci(int index) {
 
    		this.index = index;
 
	}
 
 
 
	@Override
 
	public void run() {
 
    		int first = 0;
 
    		int second = 1;
 
    		if (index == 1) {
 
        			result = first;
 
    		} else if (index == 2) {
 
        			result = second;
 
    		} else {
 
        			for (int i = 0; i < index - 2; i++) {
 
            				int temp = second;
 
            				second += first;
 
            				first = temp;
 
        			}
 
 
 
            			result = second;
 
    		}
 
	}
 
 
 
	public static void printByIndex(int index) throws InterruptedException {
 
    		Fibonacci fibonacci = new Fibonacci(index);
 
    		Thread thread = new Thread(fibonacci);
 
    		thread.start();
 
    		thread.join();
 
    		System.out.println("Fibonacci number " + index + ": " + fibonacci.result);
 
	}
 
}

Ayo mbukak cara utama ing ngisor iki :


	public static void main(String[] args) throws Exception {
    		Fibonacci.printByIndex(10);
	}

Konsol bakal nampilake:

Nomer Fibonacci 10: 34

Kode iki duwe sawetara kekurangan. Contone, minangka asil saka telpon menyang cara gabung , utas utama bakal mblokir nalika cara printByIndex dieksekusi.

Antarmuka sing bisa diarani

Saiki ayo kang katon ing antarmuka sing Jawa nyedhiyani kita metu saka kothak, kang bisa digunakake minangka alternatif kanggo Runnable . Iki antarmuka Callable :


public interface Callable<V> {
 
	V call() throws Exception;
 
}

Kaya sing sampeyan ngerteni, kaya Runnable , mung siji cara. Cara iki nduweni tujuan sing padha karo metode run - ngemot kode sing bakal dieksekusi ing benang paralel. Minangka kanggo beda, njupuk dipikir ing Nilai bali. Saiki bisa dadi jinis apa wae sing sampeyan nemtokake nalika ngetrapake antarmuka:


public class CurrentDate implements Callable<Long> {
 
	@Override
 
	public Long call() {
 
    		return new Date().getTime();
 
	}
 
}

Conto liyane:


Callable<String> task = () -> {
 
	Thread.sleep(100);
 
	return "Done";
 
};

Mangkene liyane sing migunani - cara telpon bisa mbuwang Exception . Tegese, ora kaya metode run , ing metode panggilan kita ora kudu nangani pengecualian sing dicenthang sing kedadeyan ing metode kasebut:


public class Sleep implements Runnable {

	@Override

	public void run() {

    	    try {

        	        Thread.sleep(1000);

    	    } catch (InterruptedException ignored) {

    	    }

	}

}

public class Sleep implements Callable {

	@Override

	public Object call() throws InterruptedException {

    	    Thread.sleep(1000);

    	    return null;

	}

}

Antarmuka mangsa ngarep

Antarmuka liyane sing bisa digunakake kanthi rapet karo Callable yaiku Future . Masa depan nggambarake asil komputasi asynchronous (paralel) (nilai sing dibalekake kanthi metode panggilan ). Ngidini sampeyan mriksa apa petungan wis rampung, ngenteni petungan rampung, entuk asil petungan, lan liya-liyane.

Metode antarmuka Future

  • boolean isDone () - cara iki ngasilake bener yen tugas iki (komputasi) wis rampung. Tugas sing rampung biasane, rampung karo pangecualian, utawa dibatalake dianggep rampung.

  • V njaluk () - yen perlu, cara iki pamblokiran Utas sing disebut, lan ngasilake asil petungan nalika lagi rampung.

  • V entuk (wektu entek dawa, unit TimeUnit) - kaya cara sadurunge, cara iki mblokir thread sing diarani, ngenteni asil, nanging mung kanggo wektu sing ditemtokake dening paramèter metode.

  • boolean cancel(boolean mayInterruptIfRunning) — cara iki nyoba kanggo mungkasi eksekusi tugas. Yen tugas durung diwiwiti, tugas kasebut ora bakal ditindakake. Yen tugas lagi ditindakake, parameter mayInterruptIfRunning nemtokake manawa ana upaya kanggo ngganggu thread sing nindakake tugas kasebut. Sawise metode mbatalake diarani, metode isDone bakal bali bener .

  • boolean isCancelled () - cara iki bali bener yen tugas dibatalake sadurunge rampung biasane. Cara kasebut bakal tansah ngasilake bener yen metode mbatalake sadurunge diarani lan bali bener .

Conto kode nggunakake Callable lan Future


import java.util.HashMap;
 
import java.util.Map;
 
import java.util.concurrent.*;
 
 
 
public class Fibonacci implements Callable<Integer> {
 
 
 
	private final int index;
 
 
 
	public Fibonacci(int index) {
 
    		this.index = index;
 
	}
 
 
 
	@Override
 
	public Integer call() {
 
    		int first = 0;
 
    		int second = 1;
 
    		if (index == 1) {
 
        			return first;
 
    		} else if (index == 2) {
 
        			return second;
 
    		} else {
 
        		for (int i = 0; i < index - 2; i++) {
 
            			int temp = second;
 
            			second += first;
 
            			first = temp;
 
        		}
 
 
 
        			return second;
 
    		}
 
	}
 
 
 
	public static Future<Integer> calculateAsync(int index) throws Exception {
 
    		Fibonacci fibonacci = new Fibonacci(index);
 
 
 
    		// The future object will represent the result of running the fibonacci task.
 
    		FutureTask<Integer> future = new FutureTask<>(fibonacci);
 
 
 
    		// Because the FutureTask class implements both the Future interface and the Runnable interface,
 
	 	// you can pass instances of it to the Thread constructor
 
    		Thread thread = new Thread(future);
 
    		thread.start();
 
 
 
    		return future;
 
	}
 
}

Ayo mbukak cara utama ing ngisor iki :


	public static void main(String[] args) throws Exception {
    		Map<Integer, Future<Integer>> tasks = new HashMap<>();
    		for (int i = 10; i < 20; i++) {
        			tasks.put(i, Fibonacci.calculateAsync(i));
    		}
 
    		for (Map.Entry<Integer, Future<Integer>> entry : tasks.entrySet()) {
        			Future<Integer> task = entry.getValue();
        			int index = entry.getKey();
        			int result;
        			// Check whether the task is done
        			if (task.isDone()) {
            				// Get the result of the calculations
            				result = task.get();
        			} else {
            				try {
                				// Wait another 100 milliseconds for the result of the calculations
                				result = task.get(100, TimeUnit.MILLISECONDS);
            				} catch (TimeoutException e) {
                				// Interrupt the task
                				task.cancel(true);
                				System.out.println("Fibonacci number " + index + " could not be calculated in the allotted time.");
                				return;
            				}
        			}
        			System.out.println("Fibonacci number " + index + ": " + result);
    		}
	}

Konsol bakal nampilake:

Nomer Fibonacci 16: 610
Nomer Fibonacci 17: 987 Nomer
Fibonacci 18: 1597 Nomer
Fibonacci 19: 2584 Nomer Fibonacci
10: 34 Nomer
Fibonacci 11: 55 Nomer
Fibonacci 12
: 89
Nomer Fibonacci 413: Nomer Fibonacci 413
15: 377