مشخصات مقاله
-
1307
-
0.0
-
4881
-
0
-
0
آموزش Java – synchronization و مدیریت دسترسی thread ها به منابع مشترک در Java
آموزش Java – synchronization و مدیریت دسترسی thread ها به منابع مشترک در Java
synchronization در جاوا به معنی قابلیت مدیریت دسترسی thread ها به منابع مشترک می باشد.
synchronization زمانی بسیار کاربردی تلقی می شود که توسعه دهنده بخواهد به تنها یک thread امکان دسترسی به منبع مشترک را بدهد.
هنگامی که چند thread به طور همزمان اجرا می شوند، ممکن است همه بخواهند به یک منبع همزمان دسترسی داشته باشند، در چنین شرایطی معمولا نتایج پیش بینی نشده رخ می دهد. برای مثال می توان به زمانی اشاره کرد که دو thread بخواهند اطلاعاتی را در یک فایل درج کنند. در چنین شرایطی اطلاعات به صورت ناصحیح در فایل ذخیره می شوند.
synchronization به شما امکان می دهد تا در آن واحد فقط به یک thread امکان دسترسی به منبع مورد نظر را بدهید.
دلیل استفاده از Synchronization
- جلوگیری از تداخل thread ها
- جهت جلوگیری از رخداد عدم پایایی و تضمین سازگاری (consistency )
انواع Synchronization
دو نوع synchronization وجود دارد:
- Process Synchronization
- Thread Synchronization
در مبحث حاضر به شرح thread synchronization می پردازیم.
Thread Synchronization
دو نوع thread synchronization وجود دارد: 1. فقط یک thread در آن واحد یا Mutual Exclusive 2. تعامل و همکاری بین thread ها در جاوا یا Cooperation (Inter-thread communication)
mutual exclusive خود به سه روش انجام می شود:
- متد Synchronized
- قطعه کد Synchronized
- static synchronization
Mutual Exclusive
Mutual Exclusive مانع از این می شود که thread ها به هنگام اشتراک گذاری داده ها با یکدیگر تداخل پیدا کنند. این نوع مدیریت دسترسی thread ها به منابع به سه روش زیر در جاوا قابل پیاده سازی می باشد.
- با استفاده از متد synchronized
- قطعه کد synchronized
- 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