ריבוי השרשורים וסנכרון נחשבים לפרק הטיפוסי בתכנות ג'אווה. בחברות פיתוח משחקים, נשאלות בעיקר שאלות ראיונות הקשורות לריבוי שרשורים. להלן רשימה של שאלות נפוצות בנושא ריבוי שרשורים וראיונות מקבילים ב-Java.
ריבוי שאלות ראיון
1) מהו ריבוי הליכי שרשור?
ריבוי שרשורים הוא תהליך של ביצוע שרשורים מרובים בו זמנית. ריבוי משימות משמש להשגת ריבוי המשימות. הוא צורך פחות זיכרון ונותן ביצועים מהירים ויעילים. היתרונות העיקריים שלו הם:
- שרשורים חולקים את אותו מרחב כתובות.
- החוט קל משקל.
- עלות התקשורת בין התהליכים נמוכה.
2) מהו השרשור?
חוט הוא תת-תהליך קל משקל. זהו נתיב נפרד של ביצוע מכיוון שכל חוט פועל במסגרת מחסנית אחרת. תהליך עשוי להכיל שרשורים מרובים. שרשורים חולקים את משאבי התהליך, אבל עדיין, הם מבוצעים באופן עצמאי.
פרטים נוספים.3) להבדיל בין תהליך לחוט?
ישנם ההבדלים הבאים בין התהליך לשרשור.
- תוכנית בביצוע נקראת התהליך ואילו; שרשור הוא תת-קבוצה של התהליך
- תהליכים הם עצמאיים ואילו חוטים הם תת-קבוצת התהליך.
- לתהליך יש מרחב כתובות שונה בזיכרון, בעוד שרשורים מכילים מרחב כתובות משותף.
- החלפת הקשר מהירה יותר בין השרשורים בהשוואה לתהליכים.
- תקשורת בין תהליכים איטית ויקרה יותר מתקשורת בין חוטים.
- כל שינוי בתהליך האב אינו משפיע על תהליך הצאצא ואילו שינויים בשרשור האב יכולים להשפיע על השרשור הצאצא.
4) מה אתה מבין בתקשורת בין חוטים?
- תהליך התקשורת בין חוטים מסונכרנים מכונה תקשורת בין חוטים.
- נעשה שימוש בתקשורת בין חוטים כדי למנוע סקר שרשורים ב-Java.
- השרשור מושהה בריצה במקטע הקריטי שלו, ושרשור אחר מורשה להיכנס (או לנעול) באותו חלק קריטי לביצוע.
- ניתן להשיג אותו בשיטות wait(), notify() ו-notifyAll().
5) מה המטרה של שיטת wait() ב-Java?
השיטה wait() מסופקת על ידי המחלקה Object ב-Java. שיטה זו משמשת לתקשורת בין חוטים ב-Java. ה-java.lang.Object.wait() משמש כדי להשהות את השרשור הנוכחי, ולהמתין עד שרשור אחר לא יקרא לשיטת notify() או notifyAll(). התחביר שלו ניתן להלן.
public final void wait()
6) מדוע יש לקרוא לשיטת wait() מהבלוק המסונכרן?
אנחנו חייבים לקרוא לשיטת ההמתנה אחרת זה יזרוק java.lang.IllegalMonitorStateException יוצא מן הכלל. יתר על כן, אנו זקוקים לשיטת wait() לתקשורת בין שרשורים עם notify() ו-notifyAll(). לכן זה חייב להיות קיים בבלוק המסונכרן לתקשורת נכונה ונכונה.
7) מהם היתרונות של ריבוי הליכים?
לתכנות ריבוי השחלות יש את היתרונות הבאים:
- ריבוי השרשורים מאפשר לאפליקציה/תוכנית להיות תמיד תגובתי לקלט, אפילו כבר פועל עם כמה משימות רקע
- ריבוי ההליכים מאפשר ביצוע מהיר יותר של משימות, מכיוון שרשורים מבוצעים באופן עצמאי.
- ריבוי השחלות מספק ניצול טוב יותר של זיכרון המטמון שכן חוטים חולקים את משאבי הזיכרון המשותפים.
- ריבוי השרשורים מפחית את מספר השרת הנדרש מכיוון ששרת אחד יכול להפעיל שרשורים מרובים בו-זמנית.
8) מהם המצבים במחזור החיים של שרשור?
לשרשור יכול להיות אחד מהמצבים הבאים במהלך חייו:
9) מה ההבדל בין תזמון מנע לחיתוך זמן?
תחת תזמון מנע, המשימה בעלת העדיפות הגבוהה ביותר מתבצעת עד שהיא נכנסת למצב המתנה או מת או שמתקיימת משימה בעדיפות גבוהה יותר. תחת חיתוך זמן, משימה מבוצעת לפרוסת זמן מוגדרת מראש ולאחר מכן נכנסת שוב למאגר המשימות המוכנות. לאחר מכן, המתזמן קובע איזו משימה צריכה לבצע לאחר מכן, בהתבסס על עדיפות וגורמים אחרים.
10) מהו החלפת הקשר?
ב-Context switching מצב התהליך (או השרשור) מאוחסן כך שניתן לשחזרו ולחדש את הביצוע מאותה נקודה מאוחר יותר. החלפת הקשר מאפשרת לתהליכים מרובים לשתף את אותו מעבד.
11) להבדיל בין המחלקה Thread לבין ממשק Runnable ליצירת Thread?
ניתן ליצור את השרשור באמצעות שתי דרכים.
- על ידי הרחבת הכיתה Thread
- על ידי הטמעת ממשק Runnable
עם זאת, ההבדלים העיקריים בין שתי הדרכים ניתנים להלן:
- על ידי הרחבת המחלקה Thread, איננו יכולים להרחיב אף מחלקה אחרת, מכיוון ש-Java אינה מאפשרת ירושות מרובות בזמן הטמעת ממשק Runnable; אנחנו יכולים גם להרחיב מחלקות בסיס אחרות (אם נדרש).
- על ידי הרחבת מחלקת ה-Thread, כל אחד מה-thread יוצר את האובייקט הייחודי ומתחבר אליו תוך יישום ממשק Runnable; שרשורים מרובים חולקים את אותו אובייקט
- מחלקה Thread מספקת שיטות מובנות שונות כגון getPriority(), isAlive ועוד רבות אחרות בעוד שהממשק Runnable מספק שיטה בודדת, כלומר, run().
12) מהי שיטת join()?
שיטת join() ממתינה עד שהשרשור ימות. במילים אחרות, זה גורם לשרשורים הפועלים כעת להפסיק לבצע עד שהשרשור אליו הוא מצטרף ישלים את המשימה שלו. שיטת ההצטרפות עמוסה מדי בכיתה Thread בדרכים הבאות.
- public void join() זורק InterruptedException
- הצטרפות ריק ציבורי (מילישניות ארוכות) זורק InterruptedException
13) תאר את המטרה והפעולה של שיטת השינה().
שיטת sleep() ב-java משמשת לחסימת שרשור לזמן מסוים, מה שאומר שהיא משהה את ביצוע השרשור לזמן מסוים. ישנן שתי שיטות לעשות זאת.
תחביר:
bash לקרוא קובץ
- שינה ריק סטטי ציבורי (מילישניות ארוכות) זורק InterruptedException
- שינה ריק סטטי ציבורי (מילישניות ארוכות, אינט ננו) זורק InterruptedException
עבודה של שיטת sleep()
כאשר אנו קוראים לשיטת sleep() היא משהה את ביצוע השרשור הנוכחי למשך הזמן הנתון ונותנת עדיפות לשרשור אחר (אם זמין). יתרה מכך, כאשר זמן ההמתנה הושלם אז שוב השרשור הקודם משנה את מצבו מממתין לניתן להרצה ומגיע במצב ריצה, וכל התהליך עובד כך עד שהביצוע לא מסתיים.
14) מה ההבדל בין wait() לשיטת sleep()?
לַחֲכוֹת() | לִישׁוֹן() |
---|---|
1) המתודה wait() מוגדרת במחלקה Object. | שיטת sleep() מוגדרת במחלקה Thread. |
2) שיטת wait() משחררת את הנעילה. | שיטת sleep() לא משחררת את הנעילה. |
15) האם אפשר לפתוח שרשור פעמיים?
לא, אנחנו לא יכולים להפעיל מחדש את השרשור, שכן ברגע ששרשור התחיל ובוצע, הוא עובר למצב מת. לכן, אם ננסה לפתוח שרשור פעמיים, הוא ייתן ל-runtimeException 'java.lang.IllegalThreadStateException'. שקול את הדוגמה הבאה.
public class Multithread1 extends Thread { public void run() { try { System.out.println('thread is executing now........'); } catch(Exception e) { } } public static void main (String[] args) { Multithread1 m1= new Multithread1(); m1.start(); m1.start(); } }
תְפוּקָה
thread is executing now........ Exception in thread 'main' java.lang.IllegalThreadStateException at java.lang.Thread.start(Thread.java:708) at Multithread1.main(Multithread1.java:13)פרטים נוספים.
16) האם נוכל לקרוא למתודה run() במקום start()?
כן, קריאה ישירה לשיטת run() היא חוקית, אך היא לא תעבוד כחוט במקום זאת היא תעבוד כאובייקט רגיל. לא יהיה החלפת הקשר בין השרשורים. כאשר אנו קוראים למתודה start() היא קוראת באופן פנימי למתודה run() אשר יוצרת מחסנית חדשה עבור שרשור בעוד קריאה ישירה ל-run() לא תיצור מחסנית חדשה.
java long to intפרטים נוספים.
17) מה לגבי שרשורי הדמון?
שרשורי הדמון הם השרשורים בעדיפות נמוכה המספקים את התמיכה והשירותים ברקע לשרשורי המשתמש. שרשור Daemon נסגר אוטומטית על ידי ה-JVM אם התוכנית נשארת עם שרשור הדמון בלבד, וכל שאר שרשורי המשתמש הסתיימו/מתו. קיימות שתי שיטות ל-Damon Thread זמינות במחלקה Thread:
18) האם נוכל להפוך את שרשור המשתמש כחשור דמון אם השרשור נפתח?
לא, אם תעשה זאת, זה יזרוק את IllegalThreadStateException. לכן, אנו יכולים ליצור שרשור דמון רק לפני תחילת השרשור.
class Testdaemon1 extends Thread{ public void run(){ System.out.println('Running thread is daemon...'); } public static void main (String[] args) { Testdaemon1 td= new Testdaemon1(); td.start(); setDaemon(true);// It will throw the exception: td. } }
תְפוּקָה
Running thread is daemon... Exception in thread 'main' java.lang.IllegalThreadStateException at java.lang.Thread.setDaemon(Thread.java:1359) at Testdaemon1.main(Testdaemon1.java:8)פרטים נוספים.
19) מהו וו כיבוי?
וו הכיבוי הוא חוט שמופעל באופן מרומז לפני כיבוי ה-JVM. אז אנחנו יכולים להשתמש בו כדי לבצע ניקוי של המשאב או לשמור את המצב כאשר JVM נכבה כרגיל או פתאומי. אנו יכולים להוסיף וו כיבוי באמצעות השיטה הבאה:
public�void�addShutdownHook(Thread�hook){}�� Runtime r=Runtime.getRuntime(); r.addShutdownHook(new MyThread());
כמה נקודות חשובות לגבי ווי כיבוי הן:
- ווי כיבוי אותחל אך ניתן להפעיל אותם רק כאשר התרחש כיבוי של JVM.
- ווי כיבוי אמינים יותר מהסיום() מכיוון שיש פחות סיכויים שווים כיבוי לא יפעלו.
- ניתן לעצור את ה-shutdown hook על ידי קריאה לשיטת halt(int) של מחלקה Runtime.
20) מתי עלינו להפסיק שרשור?
עלינו לקטוע שרשור כאשר אנו רוצים לפרוץ את מצב השינה או ההמתנה של חוט. אנו יכולים להפריע לשרשור על ידי קריאה ל-interrupt()�throwing InterruptedException.
פרטים נוספים.21) מהו הסנכרון?
סנכרון הוא היכולת לשלוט בגישה של שרשורים מרובים לכל משאב משותף. זה משומש:
- כדי למנוע הפרעות חוט.
- כדי למנוע בעיית עקביות.
כאשר השרשורים המרובים מנסים לבצע את אותה משימה, קיימת אפשרות לתוצאה שגויה, ולכן כדי להסיר בעיה זו, Java משתמשת בתהליך הסנכרון המאפשר להפעיל רק שרשור אחד בכל פעם. ניתן להשיג סנכרון בשלוש דרכים:
- בשיטה המסונכרנת
- על ידי בלוק מסונכרן
- על ידי סנכרון סטטי
תחביר לבלוק מסונכרן
synchronized(object reference expression) { //code block }פרטים נוספים.
22) מה המטרה של הבלוק הסינכרון?
ניתן להשתמש בבלוק הסינכרון לביצוע סנכרון על כל משאב ספציפי של השיטה. רק שרשור אחד בכל פעם יכול להפעיל על משאב מסוים, וכל שאר השרשורים שמנסים להיכנס לבלוק המסונכרן נחסמים.
- בלוק מסונכרן משמש לנעילת אובייקט עבור כל משאב משותף.
- היקף הבלוק המסונכרן מוגבל לבלוק עליו הוא מוחל. היקפו קטן יותר משיטה.
23) האם ניתן לנעול אובייקט Java לשימוש בלעדי על ידי שרשור נתון?
כן. אתה יכול לנעול אובייקט על ידי הכנסתו לבלוק 'מסונכרן'. האובייקט הנעול אינו נגיש לכל שרשור מלבד זה שטען אותו במפורש.
24) מהו סנכרון סטטי?
אם תבצע כל שיטה סטטית מסונכרנת, הנעילה תהיה על המחלקה ולא על האובייקט. אם אנחנו משתמשים במילת המפתח המסונכרנת לפני שיטה אז זה ינעל את האובייקט (שרשור אחד יכול לגשת לאובייקט בכל פעם) אבל אם אנחנו משתמשים בסנכרון סטטי אז זה ינעל מחלקה (שרשור אחד יכול לגשת למחלקה בכל פעם). פרטים נוספים.
25) מה ההבדל בין notify() לבין notifyAll()?
ה-notify() משמש לביטול חסימת שרשור ממתין אחד ואילו שיטת notifyAll() משמשת לביטול חסימת כל השרשורים במצב המתנה.
26)מהו המבוי הסתום?
מבוי סתום הוא מצב שבו כל שרשור מחכה למשאב המוחזק על ידי שרשור ממתין אחר. במצב זה, אף אחד מהשרשור לא מבוצע ולא מקבל את ההזדמנות להתבצע. במקום זאת, קיים מצב המתנה אוניברסלי בין כל החוטים. מבוי סתום הוא מצב מאוד מסובך שיכול לשבור את הקוד שלנו בזמן ריצה.
פרטים נוספים.27) כיצד לזהות מצב מבוי סתום? איך אפשר להימנע מזה?
אנו יכולים לזהות את מצב המבוי הסתום על ידי הפעלת הקוד ב-cmd ואיסוף ה-Thread Dump, ואם קיים מבוי סתום כלשהו בקוד, אז תופיע הודעה ב-cmd.
דרכים להימנע ממצב המבוי הסתום ב-Java:
28) מהו Thread Scheduler ב-Java?
ב-Java, כאשר אנו יוצרים את השרשורים, הם מפוקחים בעזרת Thread Scheduler, שהוא החלק של JVM. מתזמן השרשור אחראי רק להחליט איזה שרשור יש לבצע. מתזמן השרשורים משתמש בשני מנגנונים לתזמון השרשורים: Preemptive ו-Time Slicing.
סורק Java הבאמתזמן שרשור ג'אווה עובד גם כדי להחליט על הדברים הבאים עבור שרשור:
- זה בוחר את העדיפות של השרשור.
- זה קובע את זמן ההמתנה לשרשור
- זה בודק את אופי השרשור
29) האם לכל פתיל יש את הערימה שלו בתכנות מרובות פתילים?
כן, בתכנות מרובה הליכי כל חוט שומר על אזור מחסנית משלו או נפרד בזיכרון שבגללו כל חוט אינו תלוי זה בזה.
30) כיצד מושגת הבטיחות של חוט?
אם ניתן להשתמש בשיטה או באובייקט מחלקה על ידי שרשורים מרובים בו-זמנית ללא כל תנאי מירוץ, אזי המחלקה בטוחה לשרשור. בטיחות חוטים משמשת כדי להפוך תוכנית לבטוחה לשימוש בתכנות עם ריבוי חוטים. ניתן להשיג זאת בדרכים הבאות:
- סִנכְּרוּן
- שימוש במילת מפתח נדיפה
- שימוש במנגנון מבוסס נעילה
- שימוש בשיעורי עטיפה אטומית
31) מהו מצב גזע?
מצב מירוץ הוא בעיה שמתרחשת בתכנות מרובה הליכי כאשר שרשורים שונים מופעלים בו-זמנית תוך גישה למשאב משותף בו-זמנית. שימוש נכון בסינכרון יכול למנוע את מצב המירוץ.
32) מהי מילת המפתח ההפכפכה ב-java?
מילת מפתח נדיפה משמשת בתכנות מרובה הליכות כדי להשיג את בטיחות השרשור, מכיוון ששינוי במשתנה נדיף אחד גלוי לכל שאר השרשורים כך שניתן להשתמש במשתנה אחד על ידי חוט אחד בכל פעם.
33) מה אתה מבין במאגר חוטים?
- מאגר שרשורי Java מייצג קבוצה של שרשורי עובדים, אשר ממתינים להקצאת המשימה.
- חוטים במאגר החוטים נמצאים בפיקוח נותן השירות אשר שולף חוט אחד מהמאגר ומקצה לו עבודה.
- לאחר השלמת המשימה הנתונה, חוט הגיע שוב למאגר השרשורים.
- גודל מאגר החוטים תלוי במספר הכולל של החוטים שנשמרו ברזרבה לביצוע.
היתרונות של מאגר החוטים הם:
- באמצעות מאגר חוטים, ניתן לשפר את הביצועים.
- שימוש בבריכת חוטים יכולה להתרחש יציבות מערכת טובה יותר.
שאלות ראיון במקביל
34) מהם המרכיבים העיקריים של ה-API של במקביל?
ניתן לפתח את ה-API של Concurrency באמצעות המחלקה והממשקים של חבילת java.util.Concurrent. יש את המחלקות והממשקים הבאים בחבילה java.util.Concurrent.
- מוציא להורג
- FarkJoinPool
- ExecutorService
- ScheduledExecutorService
- עתיד
- TimeUnit (Enum)
- CountDownLatch
- CyclicBarrier
- סֵמָפוֹר
- ThreadFactory
- חסימת תור
- DelayQueue
- מנעולים
- Phaser
35) מהו ממשק ה-Executor ב-Concurrency API ב-Java?
ממשק המבצעים שמסופק על ידי החבילה java.util.concurrent הוא הממשק הפשוט המשמש לביצוע המשימה החדשה. שיטת execute() של ממשק ה-Executor משמשת לביצוע פקודה מסוימת. התחביר של שיטת execute() ניתן להלן.
void execute (פקודה ניתנת להרצה)
שקול את הדוגמה הבאה:
import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class TestThread { public static void main(final String[] arguments) throws InterruptedException { Executor e = Executors.newCachedThreadPool(); e.execute(new Thread()); ThreadPoolExecutor pool = (ThreadPoolExecutor)e; pool.shutdown(); } static class Thread implements Runnable { public void run() { try { Long duration = (long) (Math.random() * 5); System.out.println('Running Thread!'); TimeUnit.SECONDS.sleep(duration); System.out.println('Thread Completed'); } catch (InterruptedException ex) { ex.printStackTrace(); } } } }
תְפוּקָה
Running Thread! Thread Completed
36) מהו BlockingQueue?
ה-java.util.concurrent.BlockingQueue הוא ממשק המשנה של Queue התומך בפעולות כמו המתנה לזמינות השטח לפני הכנסת ערך חדש או המתנה שהתור לא ריק לפני אחזור אלמנט ממנו. שקול את הדוגמה הבאה.
import java.util.Random; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public class TestThread { public static void main(final String[] arguments) throws InterruptedException { BlockingQueue queue = new ArrayBlockingQueue(10); Insert i = new Insert(queue); Retrieve r = new Retrieve(queue); new Thread(i).start(); new Thread(r).start(); Thread.sleep(2000); } static class Insert implements Runnable { private BlockingQueue queue; public Insert(BlockingQueue queue) { this.queue = queue; } @Override public void run() { Random random = new Random(); try { int result = random.nextInt(200); Thread.sleep(1000); queue.put(result); System.out.println('Added: ' + result); result = random.nextInt(10); Thread.sleep(1000); queue.put(result); System.out.println('Added: ' + result); result = random.nextInt(50); Thread.sleep(1000); queue.put(result); System.out.println('Added: ' + result); } catch (InterruptedException e) { e.printStackTrace(); } } } static class Retrieve implements Runnable { private BlockingQueue queue; public Retrieve(BlockingQueue queue) { this.queue = queue; } @Override public void run() { try { System.out.println('Removed: ' + queue.take()); System.out.println('Removed: ' + queue.take()); System.out.println('Removed: ' + queue.take()); } catch (InterruptedException e) { e.printStackTrace(); } } } }
תְפוּקָה
גיל סלמאן חאן
Added: 96 Removed: 96 Added: 8 Removed: 8 Added: 5 Removed: 5
37) כיצד ליישם בעיית יצרן-צרכן באמצעות BlockingQueue?
ניתן לפתור את בעיית יצרן-צרכן באמצעות BlockingQueue בדרך הבאה.
import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.logging.Level; import java.util.logging.Logger; public class ProducerConsumerProblem { public static void main(String args[]){ //Creating shared object BlockingQueue sharedQueue = new LinkedBlockingQueue(); //Creating Producer and Consumer Thread Thread prod = new Thread(new Producer(sharedQueue)); Thread cons = new Thread(new Consumer(sharedQueue)); //Starting producer and Consumer thread prod.start(); cons.start(); } } //Producer Class in java class Producer implements Runnable { private final BlockingQueue sharedQueue; public Producer(BlockingQueue sharedQueue) { this.sharedQueue = sharedQueue; } @Override public void run() { for(int i=0; i<10; i++){ try { system.out.println('produced: ' + i); sharedqueue.put(i); } catch (interruptedexception ex) logger.getlogger(producer.class.getname()).log(level.severe, null, ex); consumer class in java implements runnable{ private final blockingqueue sharedqueue; public (blockingqueue sharedqueue) this.sharedqueue="sharedQueue;" @override void run() while(true){ system.out.println('consumed: '+ sharedqueue.take()); logger.getlogger(consumer.class.getname()).log(level.severe, < pre> <p> <strong>Output</strong> </p> <pre> Produced: 0 Produced: 1 Produced: 2 Produced: 3 Produced: 4 Produced: 5 Produced: 6 Produced: 7 Produced: 8 Produced: 9 Consumed: 0 Consumed: 1 Consumed: 2 Consumed: 3 Consumed: 4 Consumed: 5 Consumed: 6 Consumed: 7 Consumed: 8 Consumed: 9 </pre> <hr> <h3>38) What is the difference between Java Callable interface and Runnable interface?</h3> <p>The Callable interface and Runnable interface both are used by the classes which wanted to execute with multiple threads. However, there are two main differences between the both : </p> <ul> <li>A Callable interface can return a result, whereas the Runnable interface cannot return any result.</li> <li>A Callable interface can throw a checked exception, whereas the Runnable interface cannot throw checked exception. </li> <li>A Callable interface cannot be used before the Java 5 whereas the Runnable interface can be used.</li> </ul> <hr> <h3>39) What is the Atomic action in Concurrency in Java?</h3> <ul> <li>The Atomic action is the operation which can be performed in a single unit of a task without any interference of the other operations.</li> <li>The Atomic action cannot be stopped in between the task. Once started it fill stop after the completion of the task only. </li> <li>An increment operation such as a++ does not allow an atomic action.</li> <li>All reads and writes operation for the primitive variable (except long and double) are the atomic operation.</li> <li>All reads and writes operation for the volatile variable (including long and double) are the atomic operation.</li> <li>The Atomic methods are available in java.util.Concurrent package. </li> </ul> <hr> <h3>40) What is lock interface in Concurrency API in Java?</h3> <p>The java.util.concurrent.locks.Lock interface is used as the synchronization mechanism. It works similar to the synchronized block. There are a few differences between the lock and synchronized block that are given below.</p> <ul> <li>Lock interface provides the guarantee of sequence in which the waiting thread will be given the access, whereas the synchronized block doesn't guarantee it.</li> <li>Lock interface provides the option of timeout if the lock is not granted whereas the synchronized block doesn't provide that.</li> <li>The methods of Lock interface, i.e., Lock() and Unlock() can be called in different methods whereas single synchronized block must be fully contained in a single method.</li> </ul> <hr> <h3>41) Explain the ExecutorService Interface.</h3> <p>The ExecutorService Interface is the subinterface of Executor interface and adds the features to manage the lifecycle. Consider the following example.</p> <pre> import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class TestThread { public static void main(final String[] arguments) throws InterruptedException { ExecutorService e = Executors.newSingleThreadExecutor(); try { e.submit(new Thread()); System.out.println('Shutdown executor'); e.shutdown(); e.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException ex) { System.err.println('tasks interrupted'); } finally { if (!e.isTerminated()) { System.err.println('cancel non-finished tasks'); } e.shutdownNow(); System.out.println('shutdown finished'); } } static class Task implements Runnable { public void run() { try { Long duration = (long) (Math.random() * 20); System.out.println('Running Task!'); TimeUnit.SECONDS.sleep(duration); } catch (InterruptedException ex) { ex.printStackTrace(); } } } } </pre> <p> <strong>Output</strong> </p> <pre> Shutdown executor shutdown finished </pre> <hr> <h3>42) What is the difference between Synchronous programming and Asynchronous programming regarding a thread?</h3> <p> <strong>Synchronous programming: </strong> In Synchronous programming model, a thread is assigned to complete a task and hence thread started working on it, and it is only available for other tasks once it will end the assigned task.</p> <p> <strong>Asynchronous Programming: </strong> In Asynchronous programming, one job can be completed by multiple threads and hence it provides maximum usability of the various threads.</p> <hr> <h3>43) What do you understand by Callable and Future in Java?</h3> <p> <strong>Java Callable interface: </strong> In Java5 callable interface was provided by the package java.util.concurrent. It is similar to the Runnable interface but it can return a result, and it can throw an Exception. It also provides a run() method for execution of a thread. Java Callable can return any object as it uses Generic.</p> <p> <strong>Syntax:</strong> </p> <p>public interface Callable</p> <p> <strong>Java Future interface:</strong> Java Future interface gives the result of a concurrent process. The Callable interface returns the object of java.util.concurrent.Future.</p> <p>Java Future provides following methods for implementation.</p> <ul> <tr><td>cancel(boolean�mayInterruptIfRunning):</td> It is used to cancel the execution of the assigned task. </tr><tr><td>get():</td> It waits for the time if execution not completed and then retrieved the result. </tr><tr><td>isCancelled():</td> It returns the Boolean value as it returns true if the task was canceled before the completion. </tr><tr><td>isDone():</td> It returns true if the job is completed successfully else returns false. </tr></ul> <hr> <h3>44. What is the difference between ScheduledExecutorService and ExecutorService interface?</h3> <p>ExecutorServcie and ScheduledExecutorService both are the interfaces of java.util.Concurrent package but scheduledExecutorService provides some additional methods to execute the Runnable and Callable tasks with the delay or every fixed time period.</p> <h3>45) Define FutureTask class in Java? </h3> <p>Java FutureTask class provides a base implementation of the Future interface. The result can only be obtained if the execution of one task is completed, and if the computation is not achieved then get method will be blocked. If the execution is completed, then it cannot be re-started and can't be canceled.</p> <p> <strong>Syntax</strong> </p> <p>public class FutureTask extends Object implements RunnableFuture</p> <hr></10;>
38) מה ההבדל בין ממשק Java Callable לבין ממשק Runnable?
הממשק הניתן להתקשרות והממשק הניתן להרצה שניהם משמשים את המחלקות שרצו להפעיל עם שרשורים מרובים. עם זאת, ישנם שני הבדלים עיקריים בין שניהם:
- ממשק הניתן להתקשרות יכול להחזיר תוצאה, ואילו ממשק ההפעלה לא יכול להחזיר תוצאה כלשהי.
- ממשק הניתן להתקשרות יכול לזרוק חריג מסומן, ואילו ממשק ההפעלה לא יכול לזרוק חריג מסומן.
- לא ניתן להשתמש בממשק הניתן להתקשרות לפני ה-Java 5, בעוד שניתן להשתמש בממשק הניתן להרצה.
39) מהי הפעולה האטומית ב-Concurrency בג'אווה?
- הפעולה האטומית היא הפעולה שניתן לבצע ביחידה אחת של משימה ללא כל הפרעה של הפעולות האחרות.
- לא ניתן לעצור את הפעולה האטומית בין המשימה. ברגע שהתחיל זה מילוי עצור לאחר השלמת המשימה בלבד.
- פעולת תוספת כגון a++ אינה מאפשרת פעולה אטומית.
- כל פעולת הקריאה והכתיבה עבור המשתנה הפרימיטיבי (למעט ארוך וכפול) הן הפעולה האטומית.
- כל פעולת הקריאה והכתיבה עבור המשתנה הנדיף (כולל ארוך וכפול) הן הפעולה האטומית.
- השיטות האטומיות זמינות בחבילה java.util.Concurrent.
40) מהו ממשק נעילה ב-Concurrency API ב-Java?
ממשק java.util.concurrent.locks.Lock משמש כמנגנון הסנכרון. זה עובד בדומה לבלוק המסונכרן. ישנם כמה הבדלים בין המנעול לבלוק המסונכרן המפורטים להלן.
- ממשק הנעילה מספק ערובה לרצף שבו תינתן גישה לשרשור ההמתנה, בעוד שהחסימה המסונכרנת אינה מבטיחה זאת.
- ממשק הנעילה מספק אפשרות של פסק זמן אם הנעילה לא ניתנת ואילו הבלוק המסונכרן אינו מספק זאת.
- ניתן לקרוא לשיטות של ממשק נעילה, כלומר, Lock() ו-Unlock() בשיטות שונות ואילו בלוק מסונכרן יחיד חייב להיות מוכל במלואו בשיטה אחת.
41) הסבר את ממשק ExecutorService.
ממשק ה-ExecutorService הוא ממשק המשנה של ממשק ה-Executor ומוסיף את התכונות לניהול מחזור החיים. שקול את הדוגמה הבאה.
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class TestThread { public static void main(final String[] arguments) throws InterruptedException { ExecutorService e = Executors.newSingleThreadExecutor(); try { e.submit(new Thread()); System.out.println('Shutdown executor'); e.shutdown(); e.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException ex) { System.err.println('tasks interrupted'); } finally { if (!e.isTerminated()) { System.err.println('cancel non-finished tasks'); } e.shutdownNow(); System.out.println('shutdown finished'); } } static class Task implements Runnable { public void run() { try { Long duration = (long) (Math.random() * 20); System.out.println('Running Task!'); TimeUnit.SECONDS.sleep(duration); } catch (InterruptedException ex) { ex.printStackTrace(); } } } }
תְפוּקָה
Shutdown executor shutdown finished
42) מה ההבדל בין תכנות סינכרוני לתכנות אסינכרוני לגבי שרשור?
תכנות סינכרוני: במודל תכנות סינכרוני, שרשור מוקצה להשלמת משימה ומכאן שרשור התחיל לעבוד עליו, והוא זמין למשימות אחרות רק ברגע שהוא יסתיים את המשימה שהוקצתה.
תכנות אסינכרוני: בתכנות אסינכרוני, עבודה אחת יכולה להסתיים על ידי מספר שרשורים ומכאן שהיא מספקת שימושיות מרבית של השרשורים השונים.
43) מה אתה מבין ב-Callable and Future ב-Java?
ממשק Java הניתן להתקשרות: ב-Java5 הממשק הניתן להתקשרות סופק על ידי החבילה java.util.concurrent. זה דומה לממשק Runnable אבל זה יכול להחזיר תוצאה והוא יכול לזרוק חריגה. זה גם מספק שיטת run() לביצוע שרשור. Java Callable יכול להחזיר כל אובייקט כפי שהוא משתמש ב-Generic.
תחביר:
ממשק ציבורי ניתן להתקשרות
ממשק Java Future: ממשק Java Future נותן תוצאה של תהליך במקביל. הממשק Callable מחזיר את האובייקט של java.util.concurrent.Future.
Java Future מספקת את השיטות הבאות ליישום.
44. מה ההבדל בין ScheduledExecutorService לממשק ExecutorService?
ExecutorServcie ו-ScheduledExecutorService שניהם הממשקים של החבילה java.util.Concurrent, אך scheduledExecutorService מספק כמה שיטות נוספות לביצוע המשימות הניתנות להרצה והניתנות להתקשרות עם עיכוב או כל פרק זמן קבוע.
45) הגדר את המחלקה FutureTask ב-Java?
מחלקה Java FutureTask מספקת יישום בסיסי של ממשק Future. ניתן להשיג את התוצאה רק אם ביצוע משימה אחת הושלמה, ואם החישוב לא הושג אז שיטת get תיחסם. אם הביצוע הושלם, לא ניתן להפעיל אותו מחדש ולא ניתן לבטל אותו.
תחביר
מחלקה ציבורית FutureTask מרחיבה את האובייקט מיישם את RunnableFuture
10;>