أعتقد أن القراء الذين يفهمون Java multi-threading سيعرفون دورها بوضوح. يتم استخدام الكلمة الأساسية المتقلبة للإعلان عن متغيرات النوع البسيطة، مثل int وfloat وboolean وأنواع البيانات الأخرى. إذا تم إعلان أن أنواع البيانات البسيطة هذه متقلبة، تصبح العمليات عليها ذرية. ولكن هذا له قيود معينة. على سبيل المثال، n في المثال التالي ليس ذريًا:
انسخ رمز الكود كما يلي:
الحزمة الأسطورية؛
الطبقة العامة JoinThread تمتد الموضوع
{
int المتقلب العام الثابت n = 0;
تشغيل الفراغ العام ()
{
لـ (int i = 0; i < 10; i++)
يحاول
{
ن = ن + 1؛
Sleep(3); // من أجل جعل نتائج التشغيل أكثر عشوائية، قم بتأخير 3 مللي ثانية
}
قبض (الاستثناء ه)
{
}
}
يلقي الفراغ الرئيسي العام (String[] args) استثناءً
{
Thread threads[] = new Thread[100];
لـ (int i = 0; i < Threads.length; i++)
// إنشاء 100 موضوع
Threads[i] = new JoinThread();
لـ (int i = 0; i < Threads.length; i++)
// قم بتشغيل 100 موضوع تم إنشاؤه للتو
المواضيع[i].start();
لـ (int i = 0; i < Threads.length; i++)
// تابع بعد تنفيذ جميع المواضيع المائة
المواضيع[i].join();
System.out.println("n=" + JoinThread.n);
}
}
إذا كانت العملية على n ذرية، فيجب أن تكون نتيجة الإخراج النهائية n=1000، ومع ذلك، عند تنفيذ رمز المنطقة أعلاه، يكون الإخراج n غالبًا أقل من 1000، مما يوضح أن n=n+1 ليست عملية على المستوى الذري. . والسبب هو أنه بالنسبة للمتغير البسيط المُعلن أنه متقلب، إذا كانت القيمة الحالية مرتبطة بالقيمة السابقة للمتغير، فإن الكلمة الأساسية المتغيرة ليس لها أي تأثير، مما يعني أن التعبيرات التالية ليست عمليات ذرية:
انسخ رمز الكود كما يلي:
ن = ن + 1؛
ن++;
إذا كنت تريد أن تجعل هذا الموقف عملية ذرية، فأنت بحاجة إلى استخدام الكلمة الأساسية المتزامنة، ويمكن تغيير الكود أعلاه إلى النموذج التالي:
انسخ رمز الكود كما يلي:
الحزمة الأسطورية؛
الطبقة العامة JoinThread تمتد الموضوع
{
عدد صحيح عام ثابت n = 0;
الفراغ العام المتزامن المتزامن ()
{
ن++;
}
تشغيل الفراغ العام ()
{
لـ (int i = 0; i < 10; i++)
يحاول
{
inc(); // n = n + 1 تغير إلى inc();
Sleep(3); // من أجل جعل نتائج التشغيل أكثر عشوائية، قم بتأخير 3 مللي ثانية
}
قبض (الاستثناء ه)
{
}
}
يلقي الفراغ الرئيسي العام (String[] args) استثناءً
{
Thread threads[] = new Thread[100];
لـ (int i = 0; i < Threads.length; i++)
// إنشاء 100 موضوع
Threads[i] = new JoinThread();
لـ (int i = 0; i < Threads.length; i++)
// قم بتشغيل 100 موضوع تم إنشاؤه للتو
المواضيع[i].start();
لـ (int i = 0; i < Threads.length; i++)
// تابع بعد تنفيذ جميع المواضيع المائة
المواضيع[i].join();
System.out.println("n=" + JoinThread.n);
}
}
يتغير الكود أعلاه n=n+1 إلى inc()، حيث تستخدم طريقة inc الكلمة الأساسية المتزامنة لمزامنة الطريقة. لذلك، كن حذرًا عند استخدام الكلمة الأساسية volatile، فهذا لا يعني أن متغيرات النوع البسيط يتم تعديلها باستخدام volatile. جميع العمليات على هذا المتغير هي العمليات الأصلية عندما يتم تحديد قيمة المتغير بواسطة قيمته السابقة n+1، n++، وما إلى ذلك، ستكون الكلمة الأساسية المتقلبة غير صالحة. تكون العملية على المتغير على المستوى الذري فقط عندما لا تكون قيمة المتغير مرتبطة بقيمته السابقة، على سبيل المثال، n = m + 1 هو المستوى الأصلي. لذلك، يجب عليك توخي الحذر عند استخدام المفاتيح المتطايرة. إذا لم تكن متأكدًا، فيمكنك استخدام المفاتيح المتزامنة بدلاً من المفاتيح المتطايرة.