การคัดลอกรหัสมีดังนี้:
แพ็คเกจ com.yo;
นำเข้า java.util.concurrent.executorservice;
นำเข้า java.util.concurrent.executors;
นำเข้า java.util.concurrent.future;
นำเข้า java.util.concurrent.locks.lock;
นำเข้า java.util.concurrent.locks.readwriteLock;
นำเข้า java.util.concurrent.locks.reentrantlock;
นำเข้า java.util.concurrent.locks.reentrantrantreadwriteLock;
-
* ตู้เก็บของ
* แนวคิดที่สำคัญในการเขียนโปรแกรมแบบมัลติเธรดคือการล็อค
* เมื่อทำการดำเนินการธุรกรรมทรัพยากรที่ใช้ร่วมกันจะต้องถูกล็อคซึ่งทำให้มั่นใจได้ว่ามีเพียงเธรดเดียวเท่านั้นที่สามารถทำงานบนทรัพยากรเมื่อดำเนินการธุรกรรม
* สิ่งนี้ทำให้มั่นใจได้ถึงความสมบูรณ์ของข้อมูล ก่อนหน้า 5.0 ฟังก์ชั่นการล็อคถูกนำไปใช้โดยคำหลักที่ซิงโครไนซ์
-
ล็อกเกอร์ระดับสาธารณะ {
-
* ทดสอบการใช้ล็อค การใช้ล็อคในวิธีการสามารถหลีกเลี่ยงการใช้คำหลักที่ซิงโครไนซ์
-
คลาสคงที่ระดับสาธารณะ locktest {
ล็อคล็อค = ใหม่ reentrantlock (); // ล็อค
ค่าสองเท่า = 0d;
int addTimes = 0;
-
* เพิ่มมูลค่าของมูลค่า
* ดังนั้นวิธีการจะต้องซิงโครไนซ์การปฏิบัติก่อนหน้านี้คือการใช้คำหลักที่ซิงโครไนซ์ในการประกาศวิธีการ
-
โมฆะสาธารณะ addValue (double v) {
lock.lock (); // รับล็อค
System.out.println ("Locktest to addValue:" + v + ""
+ System.currentTimeMillis ());
พยายาม {
Thread.sleep (1,000);
} catch (interruptedException e) {
-
this.value += v;
this.addtimes ++;
lock.unlock (); // ปล่อยล็อค
-
Public Double GetValue () {
คืนค่านี้;
-
-
public static void testlocktest () โยนข้อยกเว้น {
locktest สุดท้าย locktest = new Locktest ();
// สร้างภารกิจใหม่ 1 และเรียกใช้วิธี addValue ของ locktest
task ที่รันได้ 1 = ใหม่ runnable () {
โมฆะสาธารณะเรียกใช้ () {
locktest.addvalue (55.55);
-
-
// สร้าง task 2 และวิธีการ getValue ของ Locktest
Runnable task2 = new runnable () {
โมฆะสาธารณะเรียกใช้ () {
System.out.println ("ค่า:" + locktest.getValue ());
-
-
// สร้างบริการการดำเนินการงานใหม่
ExecutorService CachedService = Executors.newcachedThreadPool ();
อนาคตในอนาคต = null;
// ดำเนินการงาน 1 สามครั้งในเวลาเดียวกัน
สำหรับ (int i = 0; i <3; i ++) {
future = cachedService.submit (task1);
-
// รอให้งานสุดท้าย 1 ถูกดำเนินการ
Future.get ();
// ดำเนินการงาน 2 อีกครั้งเพื่อส่งออกผลลัพธ์
future = cachedService.submit (task2);
// หลังจากรองาน 2 ให้ดำเนินการปิดบริการการดำเนินการงาน
Future.get ();
cachedservice.shutdownnow ();
-
-
* ReadWriteLock มีล็อคสองตัวในตัวหนึ่งคือล็อคการอ่านและอีกอันคือล็อคที่เขียน
* หลายเธรดสามารถรับการล็อคอ่านได้ในเวลาเดียวกัน แต่มีเพียงเธรดเดียวเท่านั้นที่สามารถล็อคเป็นลายลักษณ์อักษรได้
* และหลังจากล็อคที่เขียนถูกล็อคไม่มีเธรดที่จะล็อคได้ วิธีการที่จัดทำโดย ReadWriteLock คือ:
* readlock (): ส่งคืนล็อคอ่าน
* writelock (): ส่งคืนล็อคเป็นลายลักษณ์อักษรล็อคนี้เป็นเอกสิทธิ์
* ReadWriteLockTest เหมาะอย่างยิ่งสำหรับการจัดการการอ่านและเขียนการดำเนินการของไฟล์ที่คล้ายกัน
* คุณสามารถอ่านได้ในเวลาเดียวกันเมื่ออ่าน แต่คุณไม่สามารถเขียนได้
-
คลาสสแตติกสาธารณะ readWriteLockTest {
// ล็อค
ReadWriteLock Lock = ใหม่ reentRantReadWriteLock ();
// ค่า
ค่าสองเท่า = 0d;
int addTimes = 0;
-
* เพิ่มค่าของค่าและไม่อนุญาตให้หลายเธรดเข้ามาในวิธีการในเวลาเดียวกัน
-
โมฆะสาธารณะ addValue (double v) {
// รับ writelock และล็อค
ล็อค writeLock = lock.writeLock ();
writelock.lock ();
System.out.println ("ReadWriteLockTest ถึง AddValue:" + V + ""
+ System.currentTimeMillis ());
พยายาม {
Thread.sleep (1,000);
} catch (interruptedException e) {
-
พยายาม {
// ทำงานการเขียน
this.value += v;
this.addtimes ++;
} ในที่สุด {
// ปล่อย Writelock Lock
writelock.unlock ();
-
-
-
* รับข้อมูล เมื่อเธรดกำลังเรียกใช้วิธี addValue ข้อมูลที่ได้รับจาก getInfo อาจไม่ถูกต้อง
* ดังนั้นจึงจำเป็นต้องตรวจสอบให้แน่ใจว่าเมื่อมีการเรียกวิธีการไม่มีวิธีใดที่เรียกใช้วิธี addValue
-
สตริงสาธารณะ getInfo () {
// รับ readlock และล็อค
ล็อค readlock = lock.readlock ();
readlock.lock ();
System.out.println ("ReadWriteLockTest to getInfo"
+ System.currentTimeMillis ());
พยายาม {
Thread.sleep (1,000);
} catch (interruptedException e) {
-
พยายาม {
// ทำงานการอ่าน
ส่งคืนสิ่งนี้ value + ":" + this.addtimes;
} ในที่สุด {
// release readlock
readlock.unlock ();
-
-
-
Public Void Void PretreadWriteLockTest () โยนข้อยกเว้น {
Final ReadWriteLockTest ReadWriteLockTest = ใหม่ ReadWritElockTest ();
// สร้างภารกิจใหม่ 1 และเรียกใช้วิธี addValue ของ locktest
task_1 = new runnable () {
โมฆะสาธารณะเรียกใช้ () {
ReadWriteLockTest.addValue (55.55);
-
-
// สร้าง task 2 และวิธีการ getValue ของ Locktest
runnable task_2 = new runnable () {
โมฆะสาธารณะเรียกใช้ () {
System.out.println ("ข้อมูล:" + ReadWriteLockTest.getInfo ());
-
-
// สร้างบริการการดำเนินการงานใหม่
ExecutorService CachedService_1 = Executors.newcachedThreadPool ();
อนาคต future_1 = null;
// ดำเนินงาน 5 งานในเวลาเดียวกันซึ่งงาน 2 ครั้งแรกคือ task_1 และงานสองงานสุดท้ายคือ task_2
สำหรับ (int i = 0; i <2; i ++) {
Future_1 = CachedService_1.submit (task_1);
-
สำหรับ (int i = 0; i <2; i ++) {
Future_1 = CachedService_1.submit (task_2);
-
// งานสุดท้ายคือ task_1
Future_1 = CachedService_1.submit (task_1);
// คำสั่งการดำเนินการของ 5 งานเหล่านี้ควร:
// งานแรกจะถูกดำเนินการก่อนและงานที่สองจะถูกดำเนินการอีกครั้ง
// จากนั้นสอง task_2 จะถูกดำเนินการในเวลาเดียวกัน;
// เนื่องจากสามารถอ่านได้ในเวลาเดียวกันพวกเขาจะถูกประหารชีวิตในเวลาเดียวกัน
// task_1 สุดท้ายจะถูกดำเนินการอีกครั้ง นี่เป็นเพราะคุณไม่สามารถเขียนได้เมื่ออ่านดังนั้นคุณต้องรอจนกว่าการอ่านจะจบลงก่อนที่คุณจะเขียน
// รอให้งาน task_2 สุดท้ายถูกดำเนินการ
Future_1.get ();
cachedservice_1.shutdownnow ();
-
โมฆะคงที่สาธารณะหลัก (สตริง [] args) โยนข้อยกเว้น {
Lockers.testlocktest ();
System.out.println ("---------------------");
Lockers.TestReadWriteLockTest ();
-
-