بروز خطا
[message]
اشتراک در سوال
رای ها
[dataList]
حذف دایره های آموزش باران به روش مطمئن از Thread
سلام
توی قسمت آموزش باران گفتید که باید اون آبجکت های اضافی که 2 ثانیه از ساخته شدنشون میگذره پاک کنیم ... اما من چندین راه رو امتحان کردم همش خطای این رو میداد که نمیشه به صورت همزمان هم از آرایه استفاده کرد و هم اینکه عناصری رو ازش حذف کنیم .
مثلا یه بار یه Thread به این صورت ساختم .
Thread threadRemover = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(5000);
if(circles != null)
for(circle circle :circles)
if(System.currentTimeMillis() - circle.spawnTime >= 2000)
circles.remove(circles.indexOf(circle));
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
threadRemover.start();
یه بار دیگه هم توی قسمت onTouchEventبه این صورت کد نوشتم .
case MotionEvent.ACTION_UP: {
for (circle circle: circles)
if (System.currentTimeMillis() - circ.spawnTime >= 2000)
circles.remove(circles.indexOf(circle));
break;
و چندین روش دیگه ...
این حذف کردن عناصر اضافی رو در چه زمانی استفاده کنیم برنامه کرش نکنه ؟
برای این سوال 1 پاسخ وجود دارد.
پاسخ به سوال
uncocoder
12 سال پیش
+2
0
شما فرض کنید که آرایه الان 20 عنصر داره و در یک Thread قرار هست روی تمامی عناصر Iterate بشه و کاری انجام بشه. در همین حین یک Thread دیگر یکی از عناصر رو پاک می کنه، در این شرایط Iterator نا معتبر میشه و باعث کرش می شه. برای حل این مشکل روش های آسانی نیست اما این روشها تاکنون ابداع شده اند:
1- کلاسهای Concurrent Collection که در واقع برای مدیریت Collection ها ( مثل Array ) در برنامه های همزمان ( Concurrent ) کاربردی هستند. در واقع این کلاسها مشکل را حل نمی کنند بلکه توابعی که باعث اعمال نامعتبر در این زمینه میشود را از دسترس شما خارج می کنند ( و این متدها وجود ندارند که بتوانید اجرایشان کنید ).
2- استفاده از Main Loop های اختصاصی که در موقع مدیریت صحنه ( Scene Management ) اطلاعات زائد و اشیاء دور انداختنی، قبل حذف از حافظه ( و مثلاً از آرایه ها ) هستند.
3- استفاده از یک آرایه جایگزین برای حذف عناصر و به یکباره واریز شدن آن در آرایه اصلی. چون این کار یکبار در هر حلقه انجام می گیرد، احتمال کرش بسیار بسیار پایین است اما از نظر تئوری ممکن است.
4- استفاده از یک synchronize که مورد آموزش قرار نگرفته اما در واقع می تواند یک متد، یا بخشی از یک کد، یا یک فیلد را ایمن سازد که در صورتیکه Thread ـی با آن کار می کنند، سایر Thread ها در صف انتظار باقی بماند.
گزینه 4 از همه ساده تر و اصولی تر است اما ممکن است در کدها و الگوریتم های پیچیده باعث منتظر شدن Thread ها و در نتیجه خروجی نامناسب شود.
1- کلاسهای Concurrent Collection که در واقع برای مدیریت Collection ها ( مثل Array ) در برنامه های همزمان ( Concurrent ) کاربردی هستند. در واقع این کلاسها مشکل را حل نمی کنند بلکه توابعی که باعث اعمال نامعتبر در این زمینه میشود را از دسترس شما خارج می کنند ( و این متدها وجود ندارند که بتوانید اجرایشان کنید ).
2- استفاده از Main Loop های اختصاصی که در موقع مدیریت صحنه ( Scene Management ) اطلاعات زائد و اشیاء دور انداختنی، قبل حذف از حافظه ( و مثلاً از آرایه ها ) هستند.
3- استفاده از یک آرایه جایگزین برای حذف عناصر و به یکباره واریز شدن آن در آرایه اصلی. چون این کار یکبار در هر حلقه انجام می گیرد، احتمال کرش بسیار بسیار پایین است اما از نظر تئوری ممکن است.
4- استفاده از یک synchronize که مورد آموزش قرار نگرفته اما در واقع می تواند یک متد، یا بخشی از یک کد، یا یک فیلد را ایمن سازد که در صورتیکه Thread ـی با آن کار می کنند، سایر Thread ها در صف انتظار باقی بماند.
گزینه 4 از همه ساده تر و اصولی تر است اما ممکن است در کدها و الگوریتم های پیچیده باعث منتظر شدن Thread ها و در نتیجه خروجی نامناسب شود.
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .