نسخة الكود كما يلي:
حزمة com.yao ؛
استيراد 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.reentrantreadwritelock ؛
/**
* الخزانات
* مفهوم مهم في البرمجة متعددة الخيوط هو القفل.
* عند إجراء عمليات المعاملات ، يجب قفل المورد المشترك ، مما يضمن أنه يمكن أن يعمل مؤشر ترابط واحد فقط على المورد عند إجراء عمليات المعاملات.
* هذا يضمن سلامة البيانات. قبل 5.0 ، تم تنفيذ وظيفة القفل بواسطة الكلمة الرئيسية المتزامنة.
*/
خزانات الفئة العامة {
/**
* اختبار استخدام القفل. يمكن أن يؤدي استخدام القفل في الطريقة إلى تجنب استخدام الكلمة الرئيسية المتزامنة.
*/
اختبارات الفئة الثابتة العامة {
قفل القفل = جديد reentrantlock () ؛ // lock
قيمة مزدوجة = 0D ؛
int addTimes = 0 ؛
/**
* زيادة قيمة القيمة.
* لذلك يجب مزامنة الطريقة ، كانت الممارسة السابقة هي استخدام الكلمة الرئيسية المتزامنة في إعلان الطريقة.
*/
public void addvalue (double v) {
lock.lock () ؛ // الحصول على القفل
System.out.println ("Locktest to AddValue:" + V + ""
+ system.currentTimeMillis ()) ؛
يحاول {
thread.sleep (1000) ؛
} catch (InterruptedException e) {
}
this.value += v ؛
this.addtimes ++ ؛
lock.Unlock () ؛ // refer the lock
}
GetValue المزدوج العام () {
إرجاع هذا.
}
}
reats {public static void testlocktest () استثناء {
Locktest Locktest = New LockTest () ؛
// قم بإنشاء مهمة جديدة 1 واتصل بأسلوب AddValue للاختبار
Runnable Task1 = جديد RunNable () {
تشغيل الفراغ العام () {
locktest.addvalue (55.55) ؛
}
} ؛
// إنشاء مهمة جديدة 2 واتصل طريقة getValue الخاصة بـ LockTest
Runnable Task2 = new RunNable () {
تشغيل الفراغ العام () {
System.out.println ("value:" + locktest.getValue ()) ؛
}
} ؛
// إنشاء خدمة تنفيذ مهمة جديدة
ExecutorService CacheDservice = Executors.NewCacheDthReadPool () ؛
مستقبل المستقبل = فارغ ؛
// تنفيذ المهمة 1 ثلاث مرات في نفس الوقت.
لـ (int i = 0 ؛ i <3 ؛ i ++) {
المستقبل = cachedservice.submit (Task1) ؛
}
// انتظر حتى يتم تنفيذ المهمة الأخيرة 1
Future.get () ؛
// تنفيذ المهمة 2 مرة أخرى لإخراج النتيجة
المستقبل = cachedservice.submit (Task2) ؛
// بعد انتظار تنفيذ المهمة 2 ، أغلق خدمة تنفيذ المهام
Future.get () ؛
CacheDservice.shutdownNow () ؛
}
/**
* ReadWritelock يحتوي على قفلان مدمجان ، أحدهما هو قفل القراءة والآخر هو القفل المكتوب.
* يمكن الحصول على أقفال قراءة متعددة في نفس الوقت ، ولكن يمكن أن يحصل مؤشر ترابط واحد فقط على أقفال مكتوبة.
* وبعد قفل مكتوبة ، لا يمكن لأي موضوع الحصول على القفل. الأساليب التي توفرها ReadWritelock هي:
* readlock (): إرجاع قفل قراءة
* Writelock (): إرجاع قفل مكتوب ، هذا القفل حصري.
* ReadWritelockTest مناسب جدًا للتعامل مع عمليات القراءة والكتابة لملفات مماثلة.
* يمكنك القراءة في نفس الوقت عند القراءة ، لكن لا يمكنك الكتابة ؛
*/
الفئة الثابتة العامة readwritelocktest {
// قفل
readWritelock lock = جديد reentrantreadWritelock () ؛
// قيمة
قيمة مزدوجة = 0D ؛
int addTimes = 0 ؛
/**
* زيادة قيمة القيمة ، ولا تسمح لخيوط متعددة بإدخال الطريقة في نفس الوقت.
*/
public void addvalue (double v) {
// احصل على Writelock و Lock
lock writelock = lock.writelock () ؛
Writelock.lock () ؛
System.out.println ("ReadWritelocktest إلى AddValue:" + V + ""
+ system.currentTimeMillis ()) ؛
يحاول {
thread.sleep (1000) ؛
} catch (InterruptedException e) {
}
يحاول {
// قم بعمل الكتابة
this.value += v ؛
this.addtimes ++ ؛
} أخيراً {
// إطلاق قفل Writelock
Writelock.unlock () ؛
}
}
/**
* احصل على المعلومات. عندما يقوم مؤشر ترابط بالاتصال بالطريقة AddValue ، قد تكون المعلومات التي تم الحصول عليها بواسطة GetInfo غير صحيحة.
* لذلك ، من الضروري أيضًا التأكد من أنه عندما يتم استدعاء الطريقة ، لا توجد طريقة تستدعي طريقة AddValue.
*/
السلسلة العامة getInfo () {
// احصل على readlock وقفل
lock readlock = lock.readlock () ؛
readlock.lock () ؛
System.out.println ("ReadWritelocktest to getInfo"
+ system.currentTimeMillis ()) ؛
يحاول {
thread.sleep (1000) ؛
} catch (InterruptedException e) {
}
يحاول {
// قم بعمل القراءة
إرجاع this.value + ":" + this.addtimes ؛
} أخيراً {
// readlock
readlock.unlock () ؛
}
}
}
stative static void testReadWritelockTest () يلقي الاستثناء {
readWritelocktest readWritelockTest = جديد readWritelockTest () ؛
// قم بإنشاء مهمة جديدة 1 واتصل بأسلوب AddValue للاختبار
Runnable Task_1 = جديد RunNable () {
تشغيل الفراغ العام () {
ReadWritelocktest.addvalue (55.55) ؛
}
} ؛
// إنشاء مهمة جديدة 2 واتصل طريقة getValue الخاصة بـ LockTest
Runnable Task_2 = new RunNable () {
تشغيل الفراغ العام () {
System.out.println ("info:" + readWritelockTest.getInfo ()) ؛
}
} ؛
// إنشاء خدمة تنفيذ مهمة جديدة
ExecutorService CacheDservice_1 = Executors.NewCacheDthReadPool () ؛
Future Future_1 = null ؛
.
لـ (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) ؛
// يجب أن يكون ترتيب تنفيذ هذه المهام الخمس:
// يتم تنفيذ Task_1 الأول أولاً ، ويتم تنفيذ Task_1 الثاني مرة أخرى ؛
// ثم يتم تنفيذ اثنين من Task_2 في نفس الوقت ؛
// لأنه يمكن قراءتها في نفس الوقت ، يتم تنفيذها في نفس الوقت
// يتم تنفيذ آخر Task_1 مرة أخرى. هذا لأنه لا يمكنك الكتابة عند القراءة ، لذلك يجب أن تنتظر حتى تنتهي القراءة قبل أن تتمكن من الكتابة.
// انتظر حتى يتم تنفيذ Task_2 الأخير
Future_1.get () ؛
CacheDservice_1.shutdownNow () ؛
}
الفراغ الثابت العام (سلسلة [] args) يلقي الاستثناء {
Lockers.TestLockTest () ؛
System.out.println ("-------------------") ؛
Lockers.TestReadWritelockTest () ؛
}
}