Pambuka
Multithreading wis dibangun ing Jawa wiwit jaman biyen. Dadi ayo goleki kanthi cepet babagan apa multithreading.
Ayo njupuk pelajaran resmi saka Oracle minangka titik wiwitan: "
Pelajaran: Aplikasi "Hello World! ". Ayo ngganti kode aplikasi Hello World kita menyang ngisor iki:
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello, " + args[0]);
}
}
args
punika Uploaded paramèter input liwati nalika program diwiwiti. Ayo simpen kode iki menyang file kanthi jeneng sing cocog karo jeneng kelas lan ekstensi
.java
. Ayo kompilasi nggunakake utilitas
javac :
javac HelloWorldApp.java
Sawise iku, nelpon kode kita karo sawetara parameter, contone, Roger:
java HelloWorldApp Roger
Kode kita saiki duwe cacat serius. Yen kita ora menehi argumentasi (yaiku mung nglakokake java HelloWorldApp), kita bakal entuk kesalahan:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at HelloWorldApp.main(HelloWorldApp.java:3)
Pangecualian (yaiku kesalahan) kedadeyan ing utas sing jenenge
main
. Pranyata ana sawetara jinis serat ing Jawa? Ing kene perjalanan kita diwiwiti.
Jawa lan benang
Kanggo ngerti apa thread, sampeyan kudu ngerti carane aplikasi Java dibukak. Ayo ganti kode kaya ing ngisor iki:
class HelloWorldApp {
public static void main(String[] args) {
while (true) {
}
}
}
Saiki ayo kompilasi maneh nggunakake javac. Sabanjure, kanggo penak, kita bakal mbukak kode Jawa ing jendela sing kapisah. Ing Windows sampeyan bisa nindakake kaya iki:
start java HelloWorldApp
. Saiki, nggunakake sarana
jps , ayo ndeleng informasi apa sing bakal dicritakake Jawa:
Nomer pisanan yaiku PID utawa ID Proses, pengenal proses. Apa iku proses?
Процесс — это совокупность codeа и данных, разделяющих общее виртуальное addressное пространство.
Kanthi bantuan proses, eksekusi program sing beda-beda diisolasi saka saben liyane: saben aplikasi nggunakake area memori dhewe tanpa ngganggu program liyane. Aku menehi saran supaya maca artikel kanthi luwih rinci: "
https://habr.com/post/164487/ ". Proses ora bisa ana tanpa utas, dadi yen ana proses, paling ora ana siji utas. Kepriye kedadeyane ing Jawa? Nalika kita mbukak program Java, eksekusi kasebut diwiwiti kanthi
main
. We jenis ngetik program, supaya cara khusus iki
main
disebut titik entri, utawa "titik entri". Cara kasebut
main
kudu tansah
public static void
supaya Java Virtual Machine (JVM) bisa miwiti nglakokake program kita. Deleng "
Napa cara utama Jawa statis? " kanggo rincian liyane. Pranyata java launcher (java.exe utawa javaw.exe) minangka aplikasi prasaja (aplikasi C prasaja): ngemot macem-macem DLL, sing sejatine JVM. Peluncur Java nggawe sakumpulan panggilan Java Native Interface (JNI). JNI minangka mekanisme sing nyambungake jagad Java Virtual Machine lan jagad C++. Pranyata sing nguripake dudu JVM, nanging loader. Iku ngerti printah sing bener kanggo nglakokake kanggo miwiti JVM. Ngerti carane ngatur kabeh lingkungan perlu nggunakake telpon JNI. Organisasi lingkungan iki uga kalebu nggawe utas utama, sing biasane diarani
main
. Kanggo luwih cetha ndeleng apa Utas urip ing proses java, kita nggunakake program
jvisualvm , kang klebu ing JDK. Ngerti pid proses, kita bisa langsung mbukak data ing:
jvisualvm --openpid айдипроцесса
Apike, saben thread wis wilayah kapisah dhewe ing memori diparengake kanggo proses. Struktur memori iki diarani tumpukan. A tumpukan kasusun saka pigura. Bingkai minangka titik nelpon metode, titik eksekusi. Pigura uga bisa diwakili minangka StackTraceElement (ndeleng API Java kanggo
StackTraceElement ). Sampeyan bisa maca liyane babagan memori diparengake kanggo saben thread
kene . Yen kita ndeleng
Java API lan nggoleki tembung Thread, kita bakal weruh yen ana kelas
java.lang.Thread . Iku kelas iki sing makili stream ing Jawa, lan iku karo iki kita kudu bisa.
java.lang.Thread
Utas ing basa Jawa diwakili minangka conto kelas
java.lang.Thread
. Sampeyan kudu ngerti yen conto kelas Utas ing Jawa dudu benang dhewe. Iki mung jenis API kanggo thread tingkat rendah sing dikelola dening JVM lan sistem operasi. Nalika kita miwiti JVM nggunakake java launcher, nggawe utas utama kanthi jeneng
main
lan sawetara utas layanan liyane. Kaya sing kasebut ing JavaDoc saka kelas Utas:
When a Java Virtual Machine starts up, there is usually a single non-daemon thread
Ana 2 jinis utas: daemon lan non-daemon. Utas daemon minangka utas latar mburi (utas layanan) sing nindakake sawetara karya ing latar mburi. Istilah sing menarik iki minangka referensi kanggo "Demon Maxwell," sing bisa sampeyan waca liyane babagan artikel Wikipedia babagan "
dhemit ." Kaya sing kasebut ing dokumentasi, JVM terus nglakokake program (proses) nganti:
- Cara Runtime.exit ora disebut
- Kabeh utas non-daemon ngrampungake karyane (ora ana kesalahan lan kajaba sing dibuwang)
Mula, rincian penting: benang daemon bisa diakhiri ing sembarang perintah sing dieksekusi. Mulane, integritas data ing wong-wong mau ora dijamin. Mulane, benang daemon cocok kanggo sawetara tugas layanan. Contone, ing Jawa ana thread sing tanggung jawab kanggo ngolah cara finalize utawa thread sing ana gandhengane karo Garbage Collector (GC). Saben utas kalebu sawetara klompok (
ThreadGroup ). Lan klompok bisa mlebu saben liyane, mbentuk sawetara hirarki utawa struktur.
public static void main(String []args){
Thread currentThread = Thread.currentThread();
ThreadGroup threadGroup = currentThread.getThreadGroup();
System.out.println("Thread: " + currentThread.getName());
System.out.println("Thread Group: " + threadGroup.getName());
System.out.println("Parent Group: " + threadGroup.getParent().getName());
}
Grup ngidini sampeyan nyepetake manajemen aliran lan nglacak. Saliyane klompok, benang duwe panangan pangecualian dhewe. Ayo katon ing conto:
public static void main(String []args) {
Thread th = Thread.currentThread();
th.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("An error occurred: " + e.getMessage());
}
});
System.out.println(2/0);
}
Divisi dening nul bakal nimbulaké kesalahan sing bakal kejiret dening handler. Yen sampeyan ora nemtokake handler dhewe, implementasine handler standar bakal bisa digunakake, sing bakal nampilake tumpukan kesalahan ing StdError. Sampeyan bisa maca liyane ing review
http://pro-java.ru/java-dlya-opytnyx/obrabotchik-neperexvachennyx-isklyuchenij-java/ ". Kajaba iku, thread duwe prioritas. Sampeyan bisa maca liyane babagan prioritas ing artikel "
Prioritas Utas Jawa ing Multithreading ".
Nggawe thread
Minangka kasebut ing dokumentasi, kita duwe 2 cara kanggo nggawe thread. Sing pertama yaiku nggawe ahli waris sampeyan. Tuladhane:
public class HelloWorld{
public static class MyThread extends Thread {
@Override
public void run() {
System.out.println("Hello, World!");
}
}
public static void main(String []args){
Thread thread = new MyThread();
thread.start();
}
}
Kaya sing sampeyan ngerteni, tugas kasebut diluncurake ing metode
run
, lan benang diluncurake ing metode
start
. Padha ora kudu bingung, amarga ... yen kita mbukak cara
run
langsung, ora thread anyar bakal diwiwiti. Iku cara
start
sing njaluk JVM kanggo nggawe thread anyar. Opsi karo turunan saka Utas ora becik amarga kita kalebu Utas ing hirarki kelas. Kerugian kapindho yaiku kita wiwit nglanggar prinsip "Tanggung Jawab Tunggal" SOLID, amarga kelas kita dadi bebarengan tanggung jawab kanggo loro ngatur thread lan kanggo sawetara tugas sing kudu dileksanakake ing thread iki. Kang bener? Jawaban kasebut ana ing cara
run
sing kita timpa:
public void run() {
if (target != null) {
target.run();
}
}
Ing ngisor iki
target
sawetara
java.lang.Runnable
, sing bisa diterusake menyang Utas nalika nggawe conto kelas. Mulane, kita bisa nindakake iki:
public class HelloWorld{
public static void main(String []args){
Runnable task = new Runnable() {
public void run() {
System.out.println("Hello, World!");
}
};
Thread thread = new Thread(task);
thread.start();
}
}
Iku uga
Runnable
antarmuka fungsional wiwit Java 1.8. Iki ngidini sampeyan nulis kode tugas kanggo benang kanthi luwih apik:
public static void main(String []args){
Runnable task = () -> {
System.out.println("Hello, World!");
};
Thread thread = new Thread(task);
thread.start();
}
Total
Dadi, muga-muga saka crita iki jelas apa stream, kepiye ana lan operasi dhasar sing bisa ditindakake. Ing
bagean sabanjure , sampeyan kudu ngerti carane benang sesambungan karo siji liyane lan apa siklus uripe. #Viacheslav
GO TO FULL VERSION