סנכרון ב-Java הוא היכולת לשלוט בגישה של שרשורים מרובים לכל משאב משותף.
סנכרון ג'אווה הוא אפשרות טובה יותר שבה אנו רוצים לאפשר לשרשור אחד בלבד לגשת למשאב המשותף.
למה להשתמש בסנכרון?
הסנכרון משמש בעיקר ל
- כדי למנוע הפרעות חוט.
- כדי למנוע בעיית עקביות.
סוגי סנכרון
ישנם שני סוגים של סנכרון
- סנכרון תהליכים
- סנכרון שרשור
כאן, נדון רק בסנכרון שרשור.
סנכרון שרשור
ישנם שני סוגים של סנכרון חוטים בלעדית הדדית ותקשורת בין חוטים.
- בלעדי הדדי
- שיטה מסונכרנת.
- בלוק מסונכרן.
- סנכרון סטטי.
- שיתוף פעולה (תקשורת בין חוטים ב-java)
בלעדי הדדי
Mutual Exclusive עוזר למנוע משרשורים להפריע זה לזה בזמן שיתוף נתונים. ניתן להשיג זאת באמצעות שלוש הדרכים הבאות:
- על ידי שימוש בשיטה מסונכרנת
- על ידי שימוש בלוק מסונכרן
- על ידי שימוש בסנכרון סטטי
מושג הנעילה ב-Java
סנכרון בנוי סביב ישות פנימית המכונה מנעול או צג. לכל חפץ יש מנעול הקשור אליו. על פי המוסכמה, שרשור הזקוק לגישה עקבית לשדות של אובייקט צריך לרכוש את המנעול של האובייקט לפני הגישה אליהם, ולאחר מכן לשחרר את המנעול כאשר הוא מסיים איתם.
מ-Java 5 החבילה java.util.concurrent.locks מכילה מספר יישומי נעילה.
הבנת הבעיה ללא סנכרון
בדוגמה זו, אין סנכרון, ולכן הפלט אינו עקבי. בוא נראה את הדוגמה:
TestSynchronization1.java
class Table{ void printTable(int n){//method not synchronized for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } class mythread1 extends thread{ table t; mythread1(table t){ this.t="t;" public void run(){ t.printtable(5); mythread2 mythread2(table t.printtable(100); testsynchronization1{ static main(string args[]){ obj="new" table(); only one object t1="new" mythread1(obj); t2="new" mythread2(obj); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 100 10 200 15 300 20 400 25 500 </pre> <h3>Java Synchronized Method</h3> <p>If you declare any method as synchronized, it is known as synchronized method.</p> <p>Synchronized method is used to lock an object for any shared resource.</p> <p>When a thread invokes a synchronized method, it automatically acquires the lock for that object and releases it when the thread completes its task.</p> <p> <strong>TestSynchronization2.java</strong> </p> <pre> //example of java synchronized method class Table{ synchronized void printTable(int n){//synchronized method for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } class mythread1 extends thread{ table t; mythread1(table t){ this.t="t;" public void run(){ t.printtable(5); mythread2 mythread2(table t.printtable(100); testsynchronization2{ static main(string args[]){ obj="new" table(); only one object t1="new" mythread1(obj); t2="new" mythread2(obj); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 10 15 20 25 100 200 300 400 500 </pre> <h3>Example of synchronized method by using annonymous class</h3> <p>In this program, we have created the two threads by using the anonymous class, so less coding is required.</p> <p> <strong>TestSynchronization3.java</strong> </p> <pre> //Program of synchronized method by using annonymous class class Table{ synchronized void printTable(int n){//synchronized method for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } public class testsynchronization3{ static void main(string args[]){ final table obj="new" table(); only one object thread t1="new" thread(){ run(){ obj.printtable(5); }; t2="new" obj.printtable(100); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 10 15 20 25 100 200 300 400 500 </pre> <hr></=5;i++){></pre></=5;i++){></pre></=5;i++){>
שיטה מסונכרנת של Java
אם אתה מצהיר על שיטה מסונכרנת, היא ידועה בתור שיטה מסונכרנת.
שיטה מסונכרנת משמשת לנעילת אובייקט עבור כל משאב משותף.
כאשר שרשור מפעיל שיטה מסונכרנת, הוא רוכש אוטומטית את הנעילה עבור אותו אובייקט ומשחרר אותו כאשר השרשור משלים את המשימה שלו.
TestSynchronization2.java
//example of java synchronized method class Table{ synchronized void printTable(int n){//synchronized method for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } class mythread1 extends thread{ table t; mythread1(table t){ this.t="t;" public void run(){ t.printtable(5); mythread2 mythread2(table t.printtable(100); testsynchronization2{ static main(string args[]){ obj="new" table(); only one object t1="new" mythread1(obj); t2="new" mythread2(obj); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 10 15 20 25 100 200 300 400 500 </pre> <h3>Example of synchronized method by using annonymous class</h3> <p>In this program, we have created the two threads by using the anonymous class, so less coding is required.</p> <p> <strong>TestSynchronization3.java</strong> </p> <pre> //Program of synchronized method by using annonymous class class Table{ synchronized void printTable(int n){//synchronized method for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } public class testsynchronization3{ static void main(string args[]){ final table obj="new" table(); only one object thread t1="new" thread(){ run(){ obj.printtable(5); }; t2="new" obj.printtable(100); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 10 15 20 25 100 200 300 400 500 </pre> <hr></=5;i++){></pre></=5;i++){>
דוגמה לשיטה מסונכרנת באמצעות מחלקה אנונימית
בתוכנית זו, יצרנו את שני השרשורים באמצעות המחלקה האנונימית, כך שנדרש פחות קידוד.
TestSynchronization3.java
//Program of synchronized method by using annonymous class class Table{ synchronized void printTable(int n){//synchronized method for(int i=1;i<=5;i++){ system.out.println(n*i); try{ thread.sleep(400); }catch(exception e){system.out.println(e);} } public class testsynchronization3{ static void main(string args[]){ final table obj="new" table(); only one object thread t1="new" thread(){ run(){ obj.printtable(5); }; t2="new" obj.printtable(100); t1.start(); t2.start(); < pre> <p> <strong>Output:</strong> </p> <pre> 5 10 15 20 25 100 200 300 400 500 </pre> <hr></=5;i++){>
=5;i++){>=5;i++){>=5;i++){>