کانال بله, جهت پشتیبانی و اطلاع رسانی کانال بله, جهت پشتیبانی و اطلاع رسانی
عضویت

آموزش Java – synchronization و مدیریت دسترسی thread ها به منابع مشترک در Java

آموزش Java – synchronization و مدیریت دسترسی thread ها به منابع مشترک در Java

synchronization در جاوا به معنی قابلیت مدیریت دسترسی thread ها به منابع مشترک می باشد.

synchronization زمانی بسیار کاربردی تلقی می شود که توسعه دهنده بخواهد به تنها یک thread امکان دسترسی به منبع مشترک را بدهد.

هنگامی که چند thread به طور همزمان اجرا می شوند، ممکن است همه بخواهند به یک منبع همزمان دسترسی داشته باشند، در چنین شرایطی معمولا نتایج پیش بینی نشده رخ می دهد. برای مثال می توان به زمانی اشاره کرد که دو thread بخواهند اطلاعاتی را در یک فایل درج کنند. در چنین شرایطی اطلاعات به صورت ناصحیح در فایل ذخیره می شوند.

synchronization به شما امکان می دهد تا در آن واحد فقط به یک thread امکان دسترسی به منبع مورد نظر را بدهید.

دلیل استفاده از Synchronization


  1. جلوگیری از تداخل thread ها
  2. جهت جلوگیری از رخداد عدم پایایی و تضمین سازگاری (consistency )

انواع Synchronization

دو نوع synchronization وجود دارد:

  1. Process Synchronization
  2. Thread Synchronization

در مبحث حاضر به شرح thread synchronization می پردازیم.

Thread Synchronization

دو نوع thread synchronization وجود دارد: 1. فقط یک thread در آن واحد یا Mutual Exclusive 2. تعامل و همکاری بین thread ها در جاوا یا Cooperation (Inter-thread communication)

mutual exclusive خود به سه روش انجام می شود:

  1. متد Synchronized
  2. قطعه کد Synchronized
  3. static synchronization

Mutual Exclusive

Mutual Exclusive مانع از این می شود که thread ها به هنگام اشتراک گذاری داده ها با یکدیگر تداخل پیدا کنند. این نوع مدیریت دسترسی thread ها به منابع به سه روش زیر در جاوا قابل پیاده سازی می باشد.

  1. با استفاده از متد synchronized
  2. قطعه کد synchronized
  3. static synchronization

مفهوم Lock در Java

مفهوم synchronizationیا قابلیت مدیریت دسترسی thread ها به منابع مشترک بر اساس موجودیت داخلی به نام lock یا monitor پایریزی شده است. هر آبجکتی یک lock متناظر دارد. به صورت پیش فرض، هر thread ای که نیاز به دسترسی سازمان یافته، ثابت و پایا به فیلدهای آبجکت دارد، باید قفل/lock آبجکت را بدست آورده و آن را بر روی آبجکت اعمال کند و زمانی که کارش با آن آبجکت به پایان رسید، قفل را از روی آن بردارد.

از ورژن 5 به بعد جاوا، java.util.concurrent.locks تعداد زیادی پیاده سازی lock در خود کپسوله دارد که توسعه دهنده می تواند از آن ها استفاده کند.

در صورت عدم استفاده از Synchronization چه خطایی رخ می دهد

در این مثال، synchronization پیاده سازی نشده است بنابراین خروجی الگو ثابت و سازمان یافته ندارد:

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);  
}  
}  
class MyThread2 extends Thread{  
Table t;  
MyThread2(Table t){  
this.t=t;  
}  
public void run(){  
t.printTable(100);  
}  
}  
class TestSynchronization1{  
public static void main(String args[]){  
Table obj = new Table();//only one object  
MyThread1 t1=new MyThread1(obj);  
MyThread2 t2=new MyThread2(obj);  
t1.start();  
t2.start();  
}  
}  

خروجی:

5
100
10
200
15
300
20
400
25
500       

متد synchronized در Java

هر متدی که با کلیدواژه ی synchronized علامت گذاری شود، تحت عنوان synchronized یا متدی که دسترسی به آبجکت مورد نظر را برای thread های مختلف مدیریت می کند، شناخته می شود.

متد synchronized بر روی منبع یا آبجکتی که چند thread می خواهند همزمان به آن دسترسی داشته باشند، قفل/lock اعمال می کند.

زمانی که یک thread متدی synchronized را صدا می زند، به صورت خودکار قفل متناظر آن را بدست می آورد، آن را بر روی منبع یا آبجکت مورد نظر اعمال نموده و زمانی که thread عملیات خود را به پایان رساند، آن قفل را از روی آبجکت برمی دارد و به اصطلاح منبع مورد نظر را آزاد می سازد.

//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);  
}  
}  
class MyThread2 extends Thread{  
Table t;  
MyThread2(Table t){  
this.t=t;  
}  
public void run(){  
t.printTable(100);  
}  
}  
public class TestSynchronization2{  
public static void main(String args[]){  
Table obj = new Table();//only one object  
MyThread1 t1=new MyThread1(obj);  
MyThread2 t2=new MyThread2(obj);  
t1.start();  
t2.start();  
}  
}  

خروجی:

5
10
15
20
25
100
200
300
400
500

مثال کاربردی از متد synchronized با تعریف کلاس های فاقد نام (anonymous class)

در این برنامه، دو thread به وسیله ی کلاس anonymous ایجاد می کنیم. بنابراین کد کمتری برای دسترسی به این قابلیت نوشته می شود.

//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{  
public static void main(String args[]){  
final Table obj = new Table();//only one object  
Thread t1=new Thread(){  
public void run(){  
obj.printTable(5);  
}  
};  
Thread t2=new Thread(){  
public void run(){  
obj.printTable(100);  
}  
};  
t1.start();  
t2.start();  
}  
}  

خروجی:

5
10
15
20
25
100
200
300
400
500
1396/08/21 4880 1307
رمز عبور : tahlildadeh.com یا www.tahlildadeh.com
نظرات شما

نظرات خود را ثبت کنید...