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
.
Kanggo 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,
CyclicBarrier
iku 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
Exchanger
iku 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
main
thread 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();
phaser.register();
System.out.println("Phasecount is " + phaser.getPhase());
testPhaser(phaser);
testPhaser(phaser);
testPhaser(phaser);
Thread.sleep(3000);
phaser.arriveAndDeregister();
System.out.println("Phasecount is " + phaser.getPhase());
}
private static void testPhaser(final Phaser phaser) {
phaser.register();
new Thread(() -> {
String name = Thread.currentThread().getName();
System.out.println(name + " arrived");
phaser.arriveAndAwaitAdvance();
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
Phaser
ing 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:
Akeh sing bisa ngomong yen iki mung cara hafalan liyane. Ing tangan siji, ya. Ing sisih liya, pitakonan iki bisa dijawab kanthi ngelingi yen
ExecutorService
iki minangka "upgrade"
Executor
. Lan
Executor
mung 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
ExecutorService
sing 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:
Executor
submit
Future
#Viacheslav
GO TO FULL VERSION