Artikel ini terutama menunjukkan skenario pemrosesan konkuren multi-threaded java melalui contoh pengguna bank yang menarik uang, sebagai berikut.
Mulailah dengan contoh: Menerapkan kode contoh untuk skenario penarikan rekening bank.
Kelas Pertama: Account.java
Kategori Akun:
package cn.edu.byr.test;public class Account {private String accountNo;private double balance;public Account(){}public Account(String accountNo,double balance){this.accountNo = accountNo;this.balance = balance;}public int hashcode(){return accountNo.hashCode();}public String getAccountNo(){return this.accountNo;}public double getBalance () {return this.balance;} public void setBalance (double balance) {this.balance = balance;} public boolean sama (objek obj) {if (this == obj) return true; if (obj! = null && obj.getclass () == akun.class) {akun target = (null && obj.getclass () == ACCOUNCE.class) {ACCOUNCET = (ACCOUND (ACCOUNT). PALSU;}} Kelas Kedua: DrawThread.java
Kelas Thread Penarikan Uang:
Paket cn.edu.byr.test; DrawThread kelas publik memperluas utas {akun privat; drawamount ganda pribadi; drawThread publik (nama string, akun akun, drawamount ganda) {super (name); this.account = akun; this.drawamount = drawamount;} public void run () () {// synchronized (akun) {akun) {) {) {) {) {) {) {) {) {) {) {) {) {) {) {) {) {) {) {) {) {) {) {) {) {/ drawamount) {System.out.println (getName () + "Dapatkan uang berhasil, ludahkan uang kertas:" + drawamount); // coba {// thread.sleep (1); //} // Catch (InterruptedException E) {// E.PrintStackTrace (); //} Account.setBalance (Account.GetBalance () - Drawamount); System.out.println ("/t Saldo adalah:" + Account.getalance ());} else System.out.println (getName () + "Dapatkan penarikan uang gagal, saldo tidak mencukupi!"); //}} public static void (string [] args) {Account AccoC = New Account ("1234.12346 Public Static Main (String [] args) {Account AccoC = New Account (" 12344.290 DrawThread ("a", acct, 800) .start (); baru drawThread ("b", acct, 800) .start ();}} Bagian yang dikomentari dalam kode di atas: (1) Blok kode sinkronisasi yang disinkronkan (2) Hibernasi utas. Jika (1) dan (2), ada banyak kemungkinan untuk hasil yang dijalankan, salah satu kemungkinan (probabilitasnya kecil), yang sesuai dengan logika normal:
B berhasil menarik uang, memuntahkan uang: 800.0
Balance adalah: 200.0
Penarikan yang gagal dan keseimbangannya tidak cukup!
Seharusnya B pertama -tama menemukan sumber daya penarikan uang dan memodifikasi saldo dengan benar sebelum mulai menilai saldo pengguna; Probabilitas ini sangat kecil, dan sebagian besar operasi akan mirip dengan situasi berikut:
Sukses menarik uang dan memuntahkan uang: 800.0
B berhasil menarik uang, memuntahkan uang: 800.0
Saldo adalah: -600.0
Balance adalah: 200.0
Ini jelas tidak masuk akal. Dari hasil berjalan, kita dapat menebak bahwa yang pertama mengambil sumber daya dan menarik jumlahnya, tetapi sebelum memodifikasi saldo, sumber daya disita oleh B; Karena saldo belum dimodifikasi, B melihat bahwa saldo masih 800, dan B masih menarik jumlahnya; Yang pertama menjalankan keseimbangan modifikasi, tetapi tidak mencetaknya, B menyambar sumber daya; B memodifikasi keseimbangan dan mencetak keseimbangan, yaitu -600; A mencetak keseimbangan, yaitu 200;
Jika (2) utas tidur, itu harus merupakan kondisi kesalahan, karena A atau B akan melepaskan sumber daya CPU karena tidur setelah mengambil jumlah, dan JVM akan menghubungi proses lain dalam keadaan siap. Yang kedua adalah menarik uang dan menilai saldo harus salah.
Jika (1) blok kode sinkronisasi yang disinkronkan ditambahkan, akun terkunci dalam badan metode run thread; maka logika eksekusi akan dijamin normal setiap saat:
Sukses menarik uang dan memuntahkan uang: 800.0
Balance adalah: 200.0
B gagal menarik uang, dan saldo tidak cukup!
Anda dapat membayangkan proses eksekusi:
Yang pertama mendahului sumber daya dan mengunci kelas akun pada awalnya di badan metode run; kemudian mulai mengeksekusi blok kode sinkron; Jika dieksekusi ke tautan tertentu di tengah, sumber daya CPU didahului oleh B; B mulai mengeksekusi, dan mengunci kelas akun di awal. Namun, ketika menambahkan kunci, Anda akan menemukan bahwa akun telah ditempati oleh A, dan itu akan disesuaikan dengan keadaan pemblokiran dan menunggu untuk melepaskan sumber daya; Setelah A mengeksekusi blok kode sinkron, kunci akun akan dirilis, dan B akan terus mengeksekusi; Saldo yang terlihat selama menjalankan B dijamin akan dimodifikasi oleh A dan akan dieksekusi secara normal sesuai dengan logika yang benar.
Meringkaskan
Di atas adalah semua konten dari artikel ini tentang analisis contoh pemrosesan concurrent multi-threaded dari pemrograman Java, dan saya harap ini akan membantu semua orang. Teman yang tertarik dapat terus merujuk ke topik terkait lainnya di situs ini. Jika ada kekurangan, silakan tinggalkan pesan untuk menunjukkannya. Terima kasih teman atas dukungan Anda untuk situs ini!