KodeGym/Blog Jawa/Acak/Luwih apik bebarengan: Jawa lan kelas Utas. Bagian I - Ut...
John Squirrels
tingkat
San Francisco

Luwih apik bebarengan: Jawa lan kelas Utas. Bagian I - Utas eksekusi

Diterbitake ing grup

Pambuka

Multithreading dibangun ing Jawa wiwit wiwitan. Dadi, ayo ndeleng kanthi ringkes babagan iki sing diarani multithreading. Luwih apik bebarengan: Jawa lan kelas Utas.  Bagian I - Utas eksekusi - 1Kita njupuk pelajaran resmi saka Oracle minangka titik referensi: " Pelajaran: Aplikasi "Hello World! ". Kita bakal rada ngowahi kode program Hello World kaya ing ngisor iki:
class HelloWorldApp {
    public static void main(String[] args) {
        System.out.println("Hello, " + args[0]);
    }
}
argspunika Uploaded paramèter input liwati nalika program diwiwiti. Simpen kode iki menyang file kanthi jeneng sing cocog karo jeneng kelas lan duwe ekstensi .java. Kompilasi nggunakake utilitas javac : javac HelloWorldApp.java. Banjur, kita mbukak kode kita karo sawetara parameter, contone, "Roger": java HelloWorldApp Roger Luwih apik bebarengan: Jawa lan kelas Utas.  Bagian I - Utas eksekusi - 2Kode kita saiki wis cacat serius. Yen sampeyan ora menehi argumen apa wae (yaiku, mung nglakokake "java HelloWorldApp"), banjur ana kesalahan:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
        at HelloWorldApp.main(HelloWorldApp.java:3)
Pangecualian (yaiku kesalahan) dumadi ing utas sing jenenge "utama". Dadi, Jawa duwe benang? Ing kene perjalanan kita diwiwiti.

Jawa lan benang

Kanggo ngerti apa thread, sampeyan kudu ngerti carane program Java diwiwiti. Ayo ganti kode kaya ing ngisor iki:
class HelloWorldApp {
    public static void main(String[] args) {
		while (true) {
			// Do nothing
		}
	}
}
Saiki ayo ngumpulake maneh karo javac. Kanggo penak, kita bakal mbukak kode Jawa ing jendela sing kapisah. Ing Windows, iki bisa ditindakake kaya mangkene: start java HelloWorldApp. Saiki kita bakal nggunakake sarana jps kanggo ndeleng informasi apa sing bisa dicritakake Jawa: Luwih apik bebarengan: Jawa lan kelas Utas.  Bagian I - Utas eksekusi - 3Nomer pisanan yaiku PID utawa ID Proses. Apa iku proses?
A process is a combination of code and data sharing a common virtual address space.
Kanthi pangolahan, program beda-beda diisolasi saka saben liyane nalika mlaku: saben aplikasi nggunakake area dhewe ing memori tanpa ngganggu program liyane. Kanggo mangerteni sing luwih lengkap, aku nyaranake maca tutorial iki: Proses lan Utas . Proses ora bisa ana tanpa utas, mula yen ana proses, mula paling ora ana siji utas. Nanging kepriye kedadeyane ing Jawa? Nalika kita miwiti program Java, eksekusi diwiwiti kanthi mainmetode kasebut. Kaya-kaya kita mlebu ing program kasebut, mula maincara khusus iki diarani titik entri. Cara kasebut mainkudu tansah "void statis publik", supaya mesin virtual Java (JVM) bisa miwiti nglakokake program kita. Kanggo informasi luwih lengkap, Apa cara utama Jawa statis?. Pranyata peluncuran Java (java.exe utawa javaw.exe) minangka aplikasi C sing prasaja: ngemot macem-macem DLL sing bener kalebu JVM. Peluncur Java nggawe sakumpulan panggilan Java Native Interface (JNI). JNI minangka mekanisme kanggo nyambungake jagad mesin virtual Jawa karo jagad C++. Dadi, peluncur dudu JVM dhewe, nanging mekanisme kanggo mbukak. Iku ngerti printah sing bener kanggo nglakokaké kanggo miwiti JVM. Iku ngerti carane nggunakake telpon JNI kanggo nyetel lingkungan perlu. Nyetel lingkungan iki kalebu nggawe utas utama, sing diarani "utama", mesthi. Kanggo luwih nggambarake benang apa sing ana ing proses Jawa, kita nggunakake file jvisualvmalat, kang klebu karo JDK. Ngerti pid saka proses, kita bisa langsung ndeleng informasi bab proses sing: jvisualvm --openpid <process id> Luwih apik bebarengan: Jawa lan kelas Utas.  Bagian I - Utas eksekusi - 4Apike, saben thread wis wilayah kapisah dhewe ing memori diparengake kanggo proses. Struktur memori iki diarani tumpukan. A tumpukan kasusun saka pigura. Pigura nggambarake aktivasi metode (panggilan metode sing durung rampung). Pigura uga bisa dituduhake minangka StackTraceElement (ndeleng API Java kanggo StackTraceElement ). Sampeyan bisa nemokake informasi luwih lengkap babagan memori sing diparengake kanggo saben thread ing diskusi kene: " Carane ora Java (JVM) nyedhiakke tumpukan kanggo saben thread ". Yen sampeyan ndeleng Java API lan nggoleki tembung "Thread", sampeyan bakal nemokake java.lang.Threadkelas. Iki kelas sing makili thread ing Jawa, lan kita kudu bisa karo. Luwih apik bebarengan: Jawa lan kelas Utas.  Bagian I - Utas eksekusi - 5

java.lang.Thread

Ing Jawa, utas diwakili dening conto kelas java.lang.Thread. Sampeyan kudu langsung ngerti yen conto kelas Utas dudu utas eksekusi. Iki mung jinis API kanggo benang tingkat rendah sing dikelola dening JVM lan sistem operasi. Nalika kita miwiti JVM nggunakake launcher Jawa, nggawe mainUtas disebut "utama" lan sawetara Utas housekeeping liyane. Kaya sing kasebut ing JavaDoc kanggo kelas Utas: When a Java Virtual Machine starts up, there is usually a single non-daemon thread. Ana 2 jinis benang: daemon lan non-daemon. Utas daemon minangka benang latar mburi (housekeeping) sing nindakake sawetara pakaryan ing latar mburi. Tembung "daemon" nuduhake setan Maxwell. Sampeyan bisa sinau luwih akeh ing artikel Wikipedia iki . Kaya sing kasebut ing dokumentasi, JVM terus nglakokake program (proses) nganti:
  • Cara Runtime.exit () diarani
  • Kabeh Utas NON-daemon ngrampungake karyane (tanpa kesalahan utawa kanthi pengecualian sing dibuwang)
Rincian penting ing ngisor iki: Utas daemon bisa diakhiri ing sembarang titik. Akibaté, ora ana jaminan babagan integritas data kasebut. Mulane, benang daemon cocok kanggo tugas housekeeping tartamtu. Contone, Jawa duwe utas sing tanggung jawab kanggo ngolah finalize()panggilan metode, yaiku benang sing ana gandhengane karo Garbage Collector (gc). Saben utas minangka bagéan saka grup ( ThreadGroup ). Lan klompok bisa dadi bagéan saka klompok liya, mbentuk hirarki utawa struktur tartamtu.
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 nggawa urutan menyang manajemen thread. Saliyane klompok, benang duwe panangan pangecualian dhewe. Delengen contone:
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 pawang sampeyan dhewe, banjur JVM bakal ngundang pawang gawan, sing bakal ngasilake jejak tumpukan pangecualian menyang StdError. Saben thread uga nduweni prioritas. Sampeyan bisa maca liyane babagan prioritas ing artikel iki: Prioritas Utas Jawa ing Multithreading .

Nggawe thread

Minangka kasebut ing dokumentasi, kita duwe 2 cara kanggo nggawe thread. Cara pisanan yaiku nggawe subclass dhewe. 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();
    }
}
Nalika sampeyan bisa ndeleng, karya saka tugas mengkono ing run()cara, nanging thread dhewe diwiwiti ing start()cara. Aja bingung cara iki: yen kita nelpon un()cara r langsung, banjur ora thread anyar bakal diwiwiti. Iku start()cara sing njaluk JVM kanggo nggawe thread anyar. Opsi iki sing kita warisake Thread wis ora apik amarga kita kalebu Thread ing hierarki kelas kita. Kerugian kapindho yaiku kita wiwit nglanggar prinsip "tanggung jawab tunggal". Yaiku, kelas kita bebarengan tanggung jawab kanggo ngontrol utas lan sawetara tugas sing kudu ditindakake ing utas iki. Apa cara sing bener? Jawaban ditemokake ing run()cara sing padha, sing kita timpa:
public void run() {
	if (target != null) {
		target.run();
	}
}
Kene, targetsawetara java.lang.Runnable, sing bisa dilewati nalika nggawe conto kelas Utas. Iki tegese 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();
    }
}
Runnableuga wis antarmuka fungsi wiwit Java 1.8. Iki ndadekake bisa nulis kode sing luwih apik kanggo tugas utas:
public static void main(String[] args) {
	Runnable task = () -> {
		System.out.println("Hello, World!");
	};
	Thread thread = new Thread(task);
	thread.start();
}

Kesimpulan

Muga-muga diskusi iki njlentrehake apa benang, kepiye carane ana benang, lan operasi dhasar apa sing bisa ditindakake nganggo benang. Ing bagean sabanjure , kita bakal nyoba mangertos kepiye benang sesambungan karo siji liyane lan njelajah siklus urip benang. 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. Part V - Executor, ThreadPool, Fork / Gabung luwih apik bebarengan: Jawa lan kelas Utas. Bab VI - Mbusak!
Komentar
  • Popular
  • Anyar
  • lawas
Sampeyan kudu mlebu kanggo ninggalake komentar
Kaca iki durung duwe komentar