چگونه جلوی بن بست در جاوا را بگیریم ؟ در زبان جاوا و بسیاری از زبان های سیستمی ممکن است حالاتی پیش بیاید که ادامه روند اجرای برنامه ممکن نباشد. این حالت زمانی اتفاق می افتد که چند thread یا برنامه در یک زمان منتظر یک منبع خاص باشند. به این حالت که همه ی برنامه ها در حال انتظار برای دیگری است deadlock یا بن بست می گویند. بن بست می تواند دلایل مختلفی داشته باشد. راه درستی برای جلوگیری از بن بست وجود ندارد.
به طور معمول بن بست زمانی اتفاق می افتد که یک شئ سنکرون شده (synchronized) منتظر قفل کردن منبعی است که توسط یک شی synchronized دیگر قفل شده است.سعی کنید برنامه زیر را اجرا کنید. این برنامه یک بن بست را نشان می دهد. در این برنامه به این دلیل بن بست رخ می دهد که هردوی threadها منتظر گرفتن منابعی است که توسط thread های دیگر گرفته شده است. هردوی آنها منتظر خواهند بود و رها نخواهند شد.
public class DeadlockDemo { public static Object addLock = new Object(); public static Object subLock = new Object(); public static void main(String args[]) { MyAdditionThread add = new MyAdditionThread(); MySubtractionThread sub = new MySubtractionThread(); add.start(); sub.start(); } private static class MyAdditionThread extends Thread { public void run() { synchronized (addLock) { int a = 10, b = 3; int c = a + b; System.out.println("ترد جمع کردن: " + c); System.out.println("گرفتن قفل اول..."); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("ترد جمع کردن:در حال انتظار..."); synchronized (subLock) { System.out.println("تردها: قفلها گرفته شده اند و انتظار..."); } } } } private static class MySubtractionThread extends Thread { public void run() { synchronized (subLock) { int a = 10, b = 3; int c = a - b; System.out.println("ترد تفریق کردن: " + c); System.out.println("در حال گرفتن قفل..."); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("ترد تفریق کردن: در حال انتظار برای قفل..."); synchronized (addLock) { System.out.println("تردها: قفلها گرفته شده اند و انتظار..."); } } } } }
خروجی کد بالا به شکل زیر خواهد بود
ترد جمع کردن: 13 ترد تفریق کردن: 7 گرفتن قفل اول ... گرفتن قفل دوم... ترد جمع کردن:در حال انتظار... تردها: قفلها گرفته شده اند و انتظار...
حال اگر در برنامه بالا ترتیب فراخوانی thread ها عوض شود مشکل بن بست حل می شود. به برنامه زیر دقت کنید:
public class DeadlockSolutionDemo { public static Object addLock = new Object(); public static Object subLock = new Object(); public static void main(String args[]) { MyAdditionThread add = new MyAdditionThread(); MySubtractionThread sub = new MySubtractionThread(); add.start(); sub.start(); } private static class MyAdditionThread extends Thread { public void run() { synchronized (addLock) { int a = 10, b = 3; int c = a + b; System.out.println("ترد جمع کردن: " + c); System.out.println("گرفتن قفل اول..."); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("ترد جمع کردن: انتظار برای قفل..."); synchronized (subLock) { System.out.println("تردها: نگه داشتن قفل های جمع و تفریق..."); } } } } private static class MySubtractionThread extends Thread { public void run() { synchronized (addLock) { int a = 10, b = 3; int c = a - b; System.out.println("ترد تفریق کردن: " + c); System.out.println("گرفتن قفل دوم..."); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("ترد جمع کردن: انتظار برای قفل..."); synchronized (subLock) { System.out.println("تردها: نگه داشتن قفل های جمع و تفریق..."); } } } } }
خروجی کد بالا به شکل زیر خواهد بود.
ترد جمع کردن: 13 گرفتن قفل اول... ترد جمع کردن: در حال انتظار برای قفل... تردها: نگه داشتن قفل های جمع و تفریق... ... ترد تفریق: 7 گرفتن قفل دوم... ترد تفریق کردن: در حال انتظار برای قفل... تردها: نگه داشتن قفل های جمع و تفریق......
بنیانگذار توسینسو و برنامه نویس
مهدی عادلی، بنیان گذار TOSINSO. کارشناس ارشد نرم افزار کامپیوتر از دانشگاه صنعتی امیرکبیر و #C و جاوا و اندروید کار می کنم. در زمینه های موبایل و وب و ویندوز فعالیت دارم و به طراحی نرم افزار و اصول مهندسی نرم افزار علاقه مندم.
زمان پاسخ گویی روز های شنبه الی چهارشنبه ساعت 9 الی 18
فقط به موضوعات مربوط به محصولات آموزشی و فروش پاسخ داده می شود