لماذا نوعان من المواضيع جافا (في بعض الحالات) أكثر من ضعفي واحد؟
-
22-07-2019 - |
سؤال
الملف: Example1.java
public class Example1 implements Runnable {
public void run() {
for(int i = 0; i < 100000000; i++) {
int x = 5;
x = x * 4;
x = x % 3;
x = x + 9000;
x = x * 923;
}
}
public static void task() {
for(int i = 0; i < 100000000; i++) {
int x = 5;
x = x * 4;
x = x % 3;
x = x + 9000;
x = x * 923;
}
for(int i = 0; i < 100000000; i++) {
int x = 9;
x = x * 2;
x = x % 4;
x = x + 3241;
x = x * 472;
}
}
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
Example1.task();
Example1.task();
Example1.task();
Example1.task();
Example1.task();
long stopTime = System.currentTimeMillis();
long runTime = stopTime - startTime;
System.out.println("Run time for one thread: " + runTime);
startTime = System.Example1();
(new Thread(new Example1())).start();
(new Thread(new Example2())).start();
(new Thread(new Example1())).start();
(new Thread(new Example2())).start();
(new Thread(new Example1())).start();
(new Thread(new Example2())).start();
(new Thread(new Example1())).start();
(new Thread(new Example2())).start();
(new Thread(new Example1())).start();
(new Thread(new Example2())).start();
stopTime = System.currentTimeMillis();
runTime = stopTime - startTime;
System.out.println("Run time for two threads: " + runTime);
}
}
الملف: Example2.java
public class Example2 implements Runnable {
public void run() {
for(int i = 0; i < 100000000; i++) {
int x = 9;
x = x * 2;
x = x % 4;
x = x + 3241;
x = x * 472;
}
}
}
عند تشغيل هذه، ومن إخراج:
<اقتباس فقرة>وتشغيل الوقت المناسب لموضوع واحد: 1219
وتشغيل الساعة لمدة المواضيع: 281
اقتباس فقرة>وأو شيء قريب جدا.
لماذا لا يوجد مثل هذا الاختلاف؟ لماذا تقسيمها إلى قسمين المواضيع تذهب أكثر من مرتين أسرع من مجرد تشغيله مباشرة؟
المحلول
وأنت في الواقع لا تنتظر المواضيع لإنهاء على الإطلاق.
وبمجرد البدء في نشر موضوع، يجب عليك ثم استدعاء .join () على أن انتظر حتى يكتمل. ما يحدث هنا هو أن جميع المواضيع الخاصة بك بدأت وحالما بدأ آخر واحد، وكنت على مدار الساعة ومن ثم حساب الوقت توقف. وهذا يعني أن المواضيع الخاصة بك لا تزال تعمل في الخلفية.
وتحرير: السبب الأول يأخذ وقتا طويلا لأن كنت صنع سلسلة من المكالمات متزامن، في حين خلق موضوع والبدء بتشغيله يولد مهمة متزامنة
وتحرير 2: هنا منديل تسلسل مخطط من ما يحدث في أول اختبار الخاص بك: http://www.websequencediagrams.com/cgi-bin / cdraw؟ كيه سي = TWFpbi0-RXhhbXBsZTE6IFRhc2sgc3RhcnRlZAphY3RpdmF0ZSAAGAgKACEILS0-TWFpbjogZG9uZQpkZQAYEgABWAABWAABgTFlMQo وق = منديل
وهنا منديل تسلسل مخطط من ما يحدث في الاختبار الثاني: http://www.websequencediagrams.com/cgi-bin/cdraw؟lz = TWFpbi0tPkFub255bW91cyBUaHJlYWQ6IFN0YXJ0IEV4YW1wbGUxLnRhc2soKQoACSYyAAEuAAFdAAGBOwCCPjoAgyIGPk1haW46ICJIb3cgbG9uZyBkaWQgdGhhdCB0YWtlPyIKAINmEC0AKwhUYXNrcyBiZWdpbiB0byBmaW5pc2guLi4gKHNvbWUgbWF5IGhhdmUgZW5kZWQgZWFybGllcikK وق = منديل
وتحرير 3: أنا فقط أدركت أن الثانية النقاط تسلسل مخطط كل من الأسهم إلى / نفسه / الموضوع. فهي في الواقع المواضيع المختلفة، كل مكالمة.
نصائح أخرى
وبداية المكالمة () على الموضوع يعود فورا لأنه مجرد enqueues الموضوع. فإن موضوع نفسه يبدأ تعمل في الخلفية في وقت لاحق بعض الوقت.
وهنا هو ما يحصل مع التعليمات البرمجية إضافة الانضمام إلى المواضيع:
<اقتباس فقرة>وتشغيل الوقت المناسب لموضوع واحد: 566
وتشغيل الساعة لمدة المواضيع: 294
اقتباس فقرة>والأجوبة السابقة لذا صحيحة.
وتحرير: أضفت ينضم بهذه الطريقة. يمكنك أن تفعل ذلك أفضل، ولكن لا يهم:
Thread[] t = new Thread[10];
(t[0] = new Thread(new Example1())).start();
(t[1] = new Thread(new Example2())).start();
(t[2] = new Thread(new Example1())).start();
(t[3] = new Thread(new Example2())).start();
(t[4] = new Thread(new Example1())).start();
(t[5] = new Thread(new Example2())).start();
(t[6] = new Thread(new Example1())).start();
(t[7] = new Thread(new Example2())).start();
(t[8] = new Thread(new Example1())).start();
(t[9] = new Thread(new Example2())).start();
for (Thread t1: t) {
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
لديك للانضمام كل موضوع. ومع ذلك، لا تضيعوا وقتكم في انتظار انضمام () لأنه لا يتم حظر المواضيع الأخرى. إذا الانتهاء من موضوع انها executution قبل الاتصال للانضمام، كنت مجرد الاستمرار في موضوع القادم.
وأيضا، ما يعني تعليق الاخيرة؟