JavaRush /Blog Jawa /Random-JV /Sampeyan ora bisa ngrusak Jawa karo Utas: Part VI - Kangg...
Viacheslav
tingkat

Sampeyan ora bisa ngrusak Jawa karo Utas: Part VI - Kanggo alangi!

Diterbitake ing grup

Pambuka

Aliran minangka perkara sing menarik. Ing review sadurunge, 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 " Sampeyan Ora Bisa Ngrusak Jawa nganggo Utas: Bagian I - Utas ", kita ngerti yen Utas minangka Utas. Kita ngerti yen thread nindakake sawetara tugas. Yen kita pengin tugas kita bisa mbukak ( run), banjur kita kudu nemtokake utas dadi tartamtu Runnable. Sampeyan ora bisa ngrusak Jawa karo Utas: Part VI - Kanggo alangi!  - 1Kanggo ngelingi, kita bisa nggunakake Tutorialspoint Java Online 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 yen kita duwe konsep kaya kunci. Kita maca babagan iki ing " Sampeyan Ora Bisa Ngrusak Jawa nganggo Utas: Bagian II - Sinkronisasi ." Utas bisa ngunci kunci, banjur benang liyane sing nyoba ngunci kunci bakal dipeksa ngenteni kunci dadi gratis:

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 iki wektu kanggo pirembagan bab apa liyane kita bisa nindakake sing menarik.

Semaphore

Cara paling gampang kanggo ngontrol pirang-pirang benang sing bisa digunakake bebarengan yaiku semafor. Kaya ing ril sepur. Lampu ijo urip - sampeyan bisa. Lampu abang urip - kita ngenteni. Apa sing dikarepake saka semafor? Idin. Idin ing Inggris - ijin. Kanggo entuk ijin, sampeyan kudu entuk, sing ing basa Inggris bakal entuk. Lan nalika ijin ora dibutuhake maneh, kita kudu menehi, yaiku, ngeculake utawa nyingkirake, sing ing basa Inggris bakal diluncurake. Ayo ndeleng cara kerjane. Kita kudu ngimpor kelas kasebut java.util.concurrent.Semaphore. 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);
}
Minangka kita bisa ndeleng, wis apal tembung Inggris, kita ngerti carane semaphore dianggo. Apike, syarat utama yaiku "akun" semaphore kudu duwe ijin sing positif. Mulane, sampeyan bisa miwiti kanthi minus. Lan sampeyan bisa njaluk (entuk) luwih saka 1.

CountDownLatch

Mekanisme sabanjure yaiku CountDownLatch. Countdown ing basa Inggris minangka countdown, lan Latch minangka bolt utawa latch. Tegese, yen kita nerjemahake, iki minangka latch kanthi countdown. Ing kene kita butuh impor kelas sing cocog java.util.concurrent.CountDownLatch. Iki kaya balapan utawa balapan ing ngendi kabeh wong ngumpul ing garis wiwitan lan nalika kabeh wis siyap, ijin diwenehake lan kabeh wong miwiti 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();
 	}
}
ngenteni ing Inggris - nyana. Yaiku, kita ngomong dhisik countDown. Minangka Google Translator ngandika, count mudhun minangka "tumindak ngetung angka ing urutan mbalikke menyang nol," yaiku, nindakake tumindak countdown, tujuane kanggo ngetung nganti nol. Banjur kita ngomong await- yaiku, ngenteni nganti nilai counter dadi nol. Iku menarik yen counter kuwi bisa digunakake. Kaya sing kasebut ing JavaDoc - "Nalika benang kudu bola-bali ngetung kanthi cara iki, tinimbang nggunakake CyclicBarrier", yaiku, yen sampeyan butuh pancacahan sing bisa digunakake maneh, sampeyan kudu nggunakake pilihan liyane, sing diarani CyclicBarrier.

CyclicBarrier

Minangka jeneng tabet, CyclicBarrieriku alangi cyclical. Kita kudu ngimpor kelas kasebut java.util.concurrent.CyclicBarrier. Ayo katon ing conto:

public static void main(String[] args) throws InterruptedException {
	Runnable action = () -> System.out.println("На старт!");
	CyclicBarrier berrier = new CyclicBarrier(3, action);
	Runnable task = () -> {
		try {
			berrier.await();
			System.out.println("Finished");
		} catch (BrokenBarrierException | InterruptedException e) {
			e.printStackTrace();
		}
	};
	System.out.println("Limit: " + berrier.getParties());
	for (int i = 0; i < 3; i++) {
		new Thread(task).start();
	}
}
Minangka sampeyan bisa ndeleng, utas wis dieksekusi await, yaiku, nunggu. Ing kasus iki, nilai saka alangi suda. Barrier dianggep rusak ( berrier.isBroken()) nalika countdown tekan nul. Kanggo ngreset alangi, sampeyan kudu nelpon berrier.reset(), kang ilang ing CountDownLatch.

Exchanger

Obat sabanjure yaiku Exchanger. Exchange saka Inggris dijarwakake minangka exchange utawa exchange. A Exchangeriku exchanger, sing, soko liwat kang padha ijol-ijolan. Ayo katon ing conto prasaja:

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() + " обменялся с " + withThreadName);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	};
	new Thread(task).start();
	new Thread(task).start();
}
Ing kene kita miwiti rong utas. Saben wong nglakokake metode ijol-ijolan lan ngenteni benang liyane uga nglakokake metode ijol-ijolan. Mangkono, utas bakal ngganti argumen sing wis liwati ing antarane. bab menarik. Apa dheweke ora ngelingake sampeyan apa-apa? Lan dheweke ngelingake SynchronousQueue, sing dumunung ing jantung cachedThreadPool'a. 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 kanthi ngetokake utas anyar, utas iki bakal dadi mode tunggu, amarga antrian bakal kosong. Banjur mainthread bakal antri teks "Pesen". Ing wektu sing padha, bakal mandheg kanggo wektu sing dibutuhake nganti nampa unsur teks iki saka antrian. Ing topik iki sampeyan uga bisa maca " SynchronousQueue Vs Exchanger ".

Phaser

Lan pungkasane, sing paling manis - Phaser. Kita kudu ngimpor kelas kasebut java.util.concurrent.Phaser. Ayo katon ing conto prasaja:

public static void main(String[] args) throws InterruptedException {
        Phaser phaser = new Phaser();
        // Вызывая метод register, мы регистрируем текущий поток (main) How участника
        phaser.register();
        System.out.println("Phasecount is " + phaser.getPhase());
        testPhaser(phaser);
        testPhaser(phaser);
        testPhaser(phaser);
        // Через 3 секунды прибываем к барьеру и снимаемся регистрацию. Кол-во прибывших = кол-во регистраций = пуск
        Thread.sleep(3000);
        phaser.arriveAndDeregister();
        System.out.println("Phasecount is " + phaser.getPhase());
    }

    private static void testPhaser(final Phaser phaser) {
        // Говорим, что будет +1 участник на Phaser
        phaser.register();
        // Запускаем новый поток
        new Thread(() -> {
            String name = Thread.currentThread().getName();
            System.out.println(name + " arrived");
            phaser.arriveAndAwaitAdvance(); //threads register arrival to the phaser.
            System.out.println(name + " after passing barrier");
        }).start();
    }
Conto nuduhake yen alangi, nalika nggunakake Phaser'a, rusak nalika nomer registrasi pas karo nomer rawuh ing alangi. Sampeyan bisa ngerteni luwih akeh Phasering artikel saka hub " Sinkronisasi Phaser Anyar ".

Asil

Kaya sing sampeyan ngerteni saka conto, ana macem-macem cara kanggo nyinkronake benang. Sadurungé aku nyoba ngelingi babagan multithreading, muga-muga bagean sadurunge migunani. Dheweke ujar manawa dalan kanggo multithreading diwiwiti kanthi buku "Java Concurrency in Practice". Sanajan metu ing taun 2006, wong-wong nanggapi manawa buku kasebut cukup dhasar lan isih ngemas. Contone, sampeyan bisa maca diskusi ing kene: " Apa Java Concurrency In Practice isih valid? ". Iku uga migunani kanggo maca pranala saka diskusi. Contone, ana link menyang buku " The Well-Grounded Java Developer ", sing kudu digatekake " Bab 4. Modern concurrency ". Ana maneh kabeh review babagan topik sing padha: " Apa Java cocurrency in pracitce isih relevan ing jaman java 8 ". Uga duwe tips babagan apa sing kudu diwaca supaya bisa ngerti topik kasebut. Sawisé iku, sampeyan bisa nliti buku sing apik banget kayata " Tes Praktek Programmer OCA OCP JavaSE 8 ". Kita kasengsem ing bagean kapindho, yaiku, OCP. Lan ana tes ing "∫". Buku iki ngemot pitakonan lan jawaban kanthi panjelasan. Contone: Sampeyan ora bisa ngrusak Jawa karo Utas: Part VI - Kanggo alangi!  - 3Akeh sing bisa ngomong yen iki mung cara hafalan liyane. Ing tangan siji, ya. Ing sisih liya, pitakonan iki bisa dijawab kanthi ngelingi yen ExecutorServiceiki minangka "upgrade" Executor. Lan Executormung dimaksudake kanggo ndhelikake cara nggawe benang, nanging dudu cara utama kanggo nindakake, yaiku, mlaku ing benang anyar Runnable. Mulane, execute(Callable)ora, amarga padha mung nambah cara ExecutorServicesing bisa bali . Nalika sampeyan bisa ndeleng, kita bisa apal dhaptar cara, nanging luwih gampang kanggo guess yen kita ngerti alam saka kelas dhewe. Inggih, sawetara bahan tambahan babagan topik kasebut: ExecutorsubmitFuture #Viacheslav
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION