CodeGym /Blog Jawa /Acak /Luwih apik bebarengan: Jawa lan kelas Utas. Bab VI - Mbus...
John Squirrels
tingkat
San Francisco

Luwih apik bebarengan: Jawa lan kelas Utas. Bab VI - Mbusak!

Diterbitake ing grup

Pambuka

Utas minangka perkara sing menarik. Ing review kepungkur, kita ndeleng sawetara alat sing kasedhiya kanggo ngetrapake multithreading. Ayo ndeleng apa liyane menarik sing bisa ditindakake. Ing titik iki, kita ngerti akeh. Contone, saka " Luwih apik bebarengan: Jawa lan kelas Utas. Part I - Utas eksekusi ", kita ngerti yen kelas Utas nggambarake benang eksekusi. Kita ngerti yen thread nindakake sawetara tugas. Yen kita pengin tugas kita bisa run, banjur kita kudu menehi tandha thread karo Runnable. Luwih apik bebarengan: Jawa lan kelas Utas.  Babagan VI - Fire away!  - 1Kanggo ngelingi, kita bisa nggunakake Tutorialspoint Online Java Compiler :

public static void main(String[] args){
	Runnable task = () -> {
 		Thread thread = Thread.currentThread();
		System.out.println("Hello from " + thread.getName());
	};
	Thread thread = new Thread(task);
	thread.start();
}
Kita uga ngerti manawa ana sing diarani kunci. Kita sinau babagan iki ing " Better together: Java and the Thread class. Part II — Sinkronisasi . Yen siji thread entuk kunci, banjur thread liyane sing nyoba ndarbeni kunci bakal dipeksa ngenteni kunci dibebasake:

import java.util.concurrent.locks.*;

public class HelloWorld{
	public static void main(String []args){
		Lock lock = new ReentrantLock();
		Runnable task = () -> {
			lock.lock();
			Thread thread = Thread.currentThread();
			System.out.println("Hello from " + thread.getName());
			lock.unlock();
		};
		Thread thread = new Thread(task);
		thread.start();
	}
}
Aku mikir iki wektu kanggo ngomong bab apa menarik liyane kita bisa nindakake.

Semaphore

Cara paling gampang kanggo ngontrol pirang-pirang utas sing bisa mlaku bebarengan yaiku semafor. Iku kaya sinyal sepur. Ijo tegese nerusake. Abang tegese ngenteni. Ngenteni apa saka semafor? Akses. Kanggo entuk akses, kita kudu entuk. Lan nalika akses ora dibutuhake maneh, kita kudu menehi utawa ngeculake. Ayo ndeleng carane iki bisa. Kita kudu ngimpor java.util.concurrent.Semaphorekelas. Tuladha:

public static void main(String[] args) throws InterruptedException {
	Semaphore semaphore = new Semaphore(0);
	Runnable task = () -> {
		try {
			semaphore.acquire();
			System.out.println("Finished");
			semaphore.release();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	};
	new Thread(task).start();
	Thread.sleep(5000);
	semaphore.release(1);
}
Kaya sing sampeyan ngerteni, operasi kasebut (entuk lan ngeculake) mbantu kita ngerti cara kerja semafor. Sing paling penting yaiku yen kita arep entuk akses, mula semafor kudu duwe ijin sing positif. Cacah iki bisa diwiwiti menyang nomer negatif. Lan kita bisa njaluk (entuk) luwih saka 1 ijin.

CountDownLatch

Mekanisme sabanjure yaiku CountDownLatch. Ora kaget, iki minangka latch kanthi countdown. Ing kene kita butuh pernyataan impor sing cocog kanggo java.util.concurrent.CountDownLatchkelas kasebut. Iku kaya balapan mlaku, ing ngendi kabeh wong ngumpul ing garis wiwitan. Lan yen kabeh wis siyap, kabeh wong bakal nampa sinyal wiwitan bebarengan lan diwiwiti kanthi bebarengan. Tuladha:

public static void main(String[] args) {
	CountDownLatch countDownLatch = new CountDownLatch(3);
	Runnable task = () -> {
		try {
			countDownLatch.countDown();
			System.out.println("Countdown: " + countDownLatch.getCount());
			countDownLatch.await();
			System.out.println("Finished");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	};
	for (int i = 0; i < 3; i++) {
		new Thread(task).start();
 	}
}
Kaping pisanan, kita ngandhani kancing kasebut countDown(). Google nemtokake countdown minangka "tumindak ngetung angka kanthi urutan mbalikke menyang nol". Lan banjur kita marang kancing kanggo await(), IE ngenteni nganti counter dadi nul. Apike, iki counter siji-wektu. Dokumentasi Jawa ujar, "Yen benang kudu bola-bali ngetung kanthi cara iki, gunakake CyclicBarrier". Ing tembung liyane, yen sampeyan butuh counter bisa digunakake maneh, sampeyan kudu opsi beda CyclicBarrier:.

CyclicBarrier

Minangka jeneng kasebut, CyclicBarrierminangka alangi "bisa digunakake maneh". Kita kudu ngimpor java.util.concurrent.CyclicBarrierkelas kasebut. Ayo katon ing conto:

public static void main(String[] args) throws InterruptedException {
	Runnable action = () -> System.out.println("On your mark!");
	CyclicBarrier barrier = new CyclicBarrier(3, action);
	Runnable task = () -> {
		try {
			barrier.await();
			System.out.println("Finished");
		} catch (BrokenBarrierException | InterruptedException e) {
			e.printStackTrace();
		}
	};
	System.out.println("Limit: " + barrier.getParties());
	for (int i = 0; i < 3; i++) {
		new Thread(task).start();
	}
}
Nalika sampeyan bisa ndeleng, thread nganggo awaitcara, IE ngenteni. Ing kasus iki, nilai alangan mudhun. Barrier dianggep rusak ( barrier.isBroken()) nalika countdown tekan nul. Kanggo ngreset alangi, sampeyan kudu nelpon reset()cara, kang CountDownLatchora duwe.

Exchanger

Mekanisme sabanjure yaiku Exchanger. Ing konteks iki, Exchange minangka titik sinkronisasi ing ngendi owah-owahan diganti utawa diganti. Kaya sing dikarepake, an Exchangerminangka kelas sing nindakake ijol-ijolan utawa swap. Ayo goleki conto sing paling gampang:

public static void main(String[] args) {
	Exchanger<String> exchanger = new Exchanger<>();
	Runnable task = () -> {
		try {
			Thread thread = Thread.currentThread();
			String withThreadName = exchanger.exchange(thread.getName());
			System.out.println(thread.getName() + " exchanged with " + withThreadName);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	};
	new Thread(task).start();
	new Thread(task).start();
}
Kene kita miwiti loro thread. Saben wong nganggo metode ijol-ijolan lan ngenteni benang liyane uga mbukak metode ijol-ijolan. Kanthi mengkono, benang-benang kasebut ngganti argumen sing dilewati. menarik. Apa ora ngelingake sampeyan soko? Iku kaya SynchronousQueue, kang dumunung ing jantung CachedThreadPool. Kanggo gamblang, iki contone:

public static void main(String[] args) throws InterruptedException {
	SynchronousQueue<String> queue = new SynchronousQueue<>();
	Runnable task = () -> {
		try {
			System.out.println(queue.take());
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	};
	new Thread(task).start();
	queue.put("Message");
}
Conto nuduhake yen utas anyar diwiwiti, bakal ngenteni, amarga antrian bakal kosong. Banjur benang utama nempatake senar "Pesen" menyang antrian. Apa maneh, uga bakal mandheg nganti senar iki ditampa saka antrian. Sampeyan uga bisa maca " SynchronousQueue vs Exchanger " kanggo nggoleki liyane babagan topik iki.

Phaser

Kita wis disimpen sing paling apik kanggo pungkasan - Phaser. Kita kudu ngimpor java.util.concurrent.Phaserkelas kasebut. Ayo katon ing conto prasaja:

public static void main(String[] args) throws InterruptedException {
        Phaser phaser = new Phaser();
        // By calling the register method, we register the current (main) thread as a party
        phaser.register();
        System.out.println("Phasecount is " + phaser.getPhase());
        testPhaser(phaser);
        testPhaser(phaser);
        testPhaser(phaser);
        // After 3 seconds, we arrive at the barrier and deregister. Number of arrivals = number of registrations = start
        Thread.sleep(3000);
        phaser.arriveAndDeregister();
        System.out.println("Phasecount is " + phaser.getPhase());
    }

    private static void testPhaser(final Phaser phaser) {
        // We indicate that there will be a +1 party on the Phaser
        phaser.register();
        // Start a new thread
        new Thread(() -> {
            String name = Thread.currentThread().getName();
            System.out.println(name + " arrived");
            phaser.arriveAndAwaitAdvance(); // The threads register arrival at the phaser.
            System.out.println(name + " after passing barrier");
        }).start();
    }
Conto nggambaraké sing nalika nggunakake Phaser, break alangi nalika nomer registrasi cocog nomer rawuh ing alangi. Sampeyan bisa luwih akrab Phaserkanthi maca artikel GeeksforGeeks iki .

Ringkesan

Kaya sing sampeyan ngerteni saka conto kasebut, ana macem-macem cara kanggo nyinkronake benang. Sadurunge, aku nyoba ngelingi aspek multithreading. Muga-muga cicilan sadurunge ing seri iki migunani. Sawetara wong ngomong yen dalan kanggo multithreading diwiwiti kanthi buku "Java Concurrency in Practice". Sanajan dirilis ing taun 2006, wong-wong kandha yen buku kasebut cukup dhasar lan isih relevan nganti saiki. Contone, sampeyan bisa maca diskusi ing kene: Apa "Java Concurrency In Practice" isih valid? . Iku uga migunani kanggo maca pranala ing diskusi. Contone, ana link menyang buku The Well-Grounded Java Developer , lan kita bakal nyebutake bab 4. Modern concurrency . Ana uga review kabeh babagan topik iki:Apa "Java Concurrency in Practice" Isih Berlaku Ing Era Jawa 8? Artikel kasebut uga menehi saran babagan apa sing kudu diwaca kanggo ngerti topik iki. Sawise iku, sampeyan bisa ndeleng buku sing apik kaya OCA/OCP Java SE 8 Tes Praktek Programmer . Kita kasengsem ing akronim kapindho: OCP (Oracle Certified Professional). Sampeyan bakal nemokake tes ing "Bab 20: Java Concurrency". Buku iki nduweni pitakonan lan jawaban kanthi panjelasan. Contone: Luwih apik bebarengan: Jawa lan kelas Utas.  Babagan VI - Fire away!  - 3Akeh wong sing bisa ngomong yen pitakonan iki minangka conto liyane babagan ngeling-eling metode. Ing tangan siji, ya. Ing tangan liyane, sampeyan bisa mangsuli pitakonan iki kanthi ngelingi sing ExecutorServicejenis "upgrade" saka Executor. lanExecutorTujuane kanggo ndhelikake cara nggawe benang, nanging dudu cara utama kanggo nglakokake, yaiku, miwiti obyek Runnableing benang anyar. Mulane ora ana execute(Callable)- amarga ing ExecutorService, Executormung nambah submit()cara sing bisa ngasilake Futureobyek. Mesthi wae, kita bisa ngapalake dhaptar metode, nanging luwih gampang kanggo nggawe jawaban adhedhasar kawruh kita babagan sifat kelas kasebut. Lan ing ngisor iki sawetara bahan tambahan babagan topik kasebut: Luwih apik bebarengan: Jawa lan kelas Utas. Bagian I - Utas eksekusi Luwih apik bebarengan: Jawa lan kelas Utas. Part II - Sinkronisasi Luwih apik bebarengan: Jawa lan kelas Utas. Bagean III - Interaksi Better bebarengan: Jawa lan kelas Utas. Part IV - Callable, Future, lan kanca-kanca Luwih apik bebarengan: Jawa lan kelas Utas. Bagian V - Pelaksana, ThreadPool, Fork/Join
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION