บทความนี้ส่วนใหญ่แสดงให้เห็นถึงสถานการณ์การประมวลผลแบบหลายเธรดที่เกิดขึ้นพร้อมกันผ่านตัวอย่างของผู้ใช้ธนาคารที่ถอนเงินดังต่อไปนี้
เริ่มต้นด้วยตัวอย่าง: ใช้รหัสตัวอย่างสำหรับสถานการณ์การถอนบัญชีธนาคาร
ชั้นหนึ่ง: account.java
หมวดหมู่บัญชี:
แพ็คเกจ CN.EDU.BYR.TEST; บัญชีระดับสาธารณะ {Private String AccountNo; ยอดคงเหลือสองครั้งส่วนตัวบัญชีสาธารณะ () {} บัญชีสาธารณะ (String AccountNo, Double Balance) {this.AccountNo = accountNo; this.balance = Balance; getBalance () {return this.balance;} โมฆะสาธารณะ setBalance (สมดุลสองเท่า) {this.balance = balance;} public Boolean Equals (Object obj) {ถ้า (this == obj) return true; ถ้า (obj! = null && obj.getClass () == บัญชี เท็จ;}} คลาสที่สอง: drawthread.java
ชั้นเรียนถอนเงินชั้น:
แพ็คเกจ CN.EDU.BYR.TEST; การวาดชั้นเรียนสาธารณะขยายเธรด {บัญชีส่วนบุคคล; การวาดคู่ส่วนตัว; การวาดภาพสาธารณะ (ชื่อสตริง, บัญชีบัญชี, การดึงสองครั้ง) {super (ชื่อ); this.account = บัญชี; this.drawamount = drawAmount;} public void run () drawAmount) {system.out.println (getName () + "รับเงินได้สำเร็จ, คายธนบัตร:" + drawamount); // ลอง {// thread.sleep (1); //} // catch (interruptedException e) {// e.printStackTrace (); //} account.setBalance (account.getBalance () - drawamount); System.out.println ("/t ยอดคงเหลือคือ:" + account.getBalance ());} else system.out.println (getName () + "รับเงินล้มเหลวความสมดุลไม่เพียงพอ!"); //}} โมฆะสาธารณะ Drawthread ("a", acct, 800). start (); drawthread ใหม่ ("b", acct, 800). start ();}} ส่วนที่แสดงความคิดเห็นในรหัสด้านบน: (1) บล็อกรหัสซิงโครไนซ์ซิงโครไนซ์ซิงโครไนซ์ (2) การจำศีลเธรด ถ้า (1) และ (2) มีความเป็นไปได้มากมายสำหรับผลการดำเนินการหนึ่งในความเป็นไปได้ (ความน่าจะเป็นมีขนาดเล็ก) ซึ่งสอดคล้องกับตรรกะปกติ:
B ประสบความสำเร็จในการถอนเงินคายเงิน: 800.0
ยอดคงเหลือคือ: 200.0
การถอนที่ล้มเหลวและยอดคงเหลือไม่เพียงพอ!
ควรเป็น B ครั้งแรกที่พบทรัพยากรการถอนเงินและปรับเปลี่ยนยอดคงเหลืออย่างถูกต้องก่อนที่จะเริ่มตัดสินยอดคงเหลือของผู้ใช้ ความน่าจะเป็นนี้มีขนาดเล็กมากและการดำเนินงานส่วนใหญ่จะคล้ายกับสถานการณ์ต่อไปนี้:
ถอนเงินได้สำเร็จและคายเงิน: 800.0
B ประสบความสำเร็จในการถอนเงินคายเงิน: 800.0
ยอดคงเหลือคือ: -600.0
ยอดคงเหลือคือ: 200.0
เห็นได้ชัดว่าไร้เหตุผล จากผลการดำเนินการเราสามารถเดาได้ว่าการยึดทรัพยากรครั้งแรกและถอนจำนวนเงิน แต่ก่อนที่จะแก้ไขยอดเงินคงเหลือทรัพยากรจะถูกยึดโดย B; เนื่องจากยอดคงเหลือยังไม่ได้รับการแก้ไข B เห็นว่ายอดคงเหลือยังคงอยู่ที่ 800 และ B ยังคงถอนจำนวนเงิน ครั้งแรกที่รันสมดุลการปรับเปลี่ยน แต่ไม่ได้พิมพ์ B snatches ทรัพยากร; B ปรับเปลี่ยนยอดคงเหลือและพิมพ์ยอดคงเหลือซึ่งคือ -600; พิมพ์สมดุลซึ่งก็คือ 200;
ถ้า (2) เธรดนอนหลับจะต้องเป็นเงื่อนไขข้อผิดพลาดเนื่องจาก A หรือ B จะปล่อยทรัพยากร CPU เนื่องจากการนอนหลับหลังจากดึงจำนวนเงินและ JVM จะเรียกกระบวนการอื่นในสถานะพร้อม สิ่งที่สองคือการถอนเงินและตัดสินยอดคงเหลือจะต้องผิด
หากมีการเพิ่ม (1) การเพิ่มบล็อกรหัสซิงโครไนซ์ซิงโครไนซ์บัญชีจะถูกล็อคในตัววิธีการรันเธรด จากนั้นตรรกะการดำเนินการจะรับประกันได้ว่าเป็นเรื่องปกติทุกครั้ง:
ถอนเงินได้สำเร็จและคายเงิน: 800.0
ยอดคงเหลือคือ: 200.0
B ล้มเหลวในการถอนเงินและยอดคงเหลือไม่เพียงพอ!
คุณสามารถจินตนาการถึงกระบวนการดำเนินการ:
การยึดเอาทรัพยากรครั้งแรกและล็อคคลาสบัญชีเริ่มแรกในร่างกายวิธีการเรียกใช้; จากนั้นเริ่มดำเนินการบล็อกรหัสแบบซิงโครนัส หากมีการดำเนินการไปยังลิงค์บางอย่างที่อยู่ตรงกลางทรัพยากร CPU จะถูกจองโดย B; B เริ่มดำเนินการและล็อคคลาสบัญชีที่จุดเริ่มต้น อย่างไรก็ตามเมื่อเพิ่มล็อคคุณจะพบว่าบัญชีถูกครอบครองโดย A และจะถูกปรับให้เข้ากับสถานะการบล็อกและรอให้ A ปล่อยทรัพยากร หลังจากดำเนินการบล็อกรหัสแบบซิงโครนัสการล็อคบัญชีจะถูกปล่อยออกมาและ B จะดำเนินการต่อไป ยอดคงเหลือที่เห็นในระหว่างการรัน B รับประกันว่าจะได้รับการแก้ไขโดย A และจะถูกดำเนินการตามปกติตามตรรกะที่ถูกต้อง
สรุป
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้เกี่ยวกับการวิเคราะห์อินสแตนซ์การประมวลผลที่เกิดขึ้นพร้อมกันหลายเธรดของการเขียนโปรแกรม Java และฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน เพื่อนที่สนใจสามารถอ้างถึงหัวข้ออื่น ๆ ที่เกี่ยวข้องในเว็บไซต์นี้ต่อไป หากมีข้อบกพร่องใด ๆ โปรดฝากข้อความไว้เพื่อชี้ให้เห็น ขอบคุณเพื่อนที่ให้การสนับสนุนเว็บไซต์นี้!