PDA

View Full Version : سوال: چرا الویت timer پایین تر از دستور print قرار میگیره؟



faez.ham
جمعه 27 تیر 1393, 00:04 صبح
سلامچرا توی این برنامه ، با اینکه دستور timer بالاتر از دستور print قرار داره ، اول print اجرا میشه بعدش دستور timer اجرا میشه؟(منظورم توی قسمت main برنامست.) }

import java.util.Timer;
import java.util.TimerTask;



public class hamid1
{
public int count=0;
Timer timer=new Timer();
ToDo todo=new ToDo();

/** Creates a new instance of period */

public hamid1 ()
{
timer.schedule (todo,0,1000);
}


public static void main(String args[]){

new hamid1();
System.out.print("salam \n");

}
class ToDo extends TimerTask{

int count=0;
public void run(){
{
System.out.println("Task scheduled." +count);
count++;
if (count>5)
timer.cancel ();

}

}
}

}

vahid-p
جمعه 27 تیر 1393, 11:56 صبح
شما در بحث Thread ها نمیتونید بگید، مثلا فلان دفعه Thread1 اجرا میشه و فلان دفعه Thread2 و همچنین کدوم زودتر یا کدوم دیرتر اجرا میشه. این مدیریت Thread ها رو خود JVM انجام میده.
پس اینجا هم یه Thread داریم که main هست و هر برنامه حداقل یک Thread داره که همون main هست. تو این برنامه یه Thread دیگه ایجاد شده که حالا برنامه Multi-Threading هست که در ظاهر همزمان اجرا میشن ولی خب در حد چند سیکل سی پی یو اختلافاتی پیش میاد که اهمیتی نداره. اگر اون هم اهمیت داشته باشه، اونوقت میشه از طرق مختلف تقدم و تاخرش رو کنترل کرد. یعنی میتونید خودتون Thread ها رو جوری کنترل کنید که رفتاری که میخواید رو داشته باشند. بهتره مبحثی مثل Synchronized رو در مورد Thread ها بخونید.
توجه کنید مثلا در synchronized Threads که از شی ای برای هماهنگی استفاده میشه یا بهتر بگم عدم تداخل، ولی باز هم اینجا نمیتونید بگید کدوم زودتر شروع میشه، چون اونی که دسترسیش به شی زودتر باشه رو نمیتونید از قبل مشخص کنید مگر اینکه برای این هم کدی بنویسید که مجبور کنید اول فلان اجرا بشه بعد این.

از اینها بگذریم، حتی شما 1 نانوثانیه بین ساخت Timer و System.out.println("salam") تاخیر ایجاد کنید، میبینید اول Task scheduled.0 نوشته میشه بعد salam. البته استفاده از تاخیر برای کنترل Thread ها اصلا روش خوبی نیست.

اینو تست کن :
public static void main(String args[]) throws InterruptedException {
new hamidi1();
Thread.sleep(0, 1); //تاخیر 1 نانوثانیه
System.out.print("salam \n");
}

faez.ham
شنبه 28 تیر 1393, 12:20 عصر
من اون تاخیر 1 نانوثانیه رو به 1000 هم تبدیل کردم ولی هیچ فرقی نکرد

چیز دیگه ای به ذهنتون نمیرسه که بتونم مشکل رو پیدا کنم ؟

vahid-p
شنبه 28 تیر 1393, 23:24 عصر
اینجا مشکلی وجود نداره ولی برام جای تعجبه چطور با 1000 نانوثانیه باز هم اول پیغام salam رو پرینت میکنه براتون. البته باز هم نمیشه اسم مشکل روش گذاشت. چون در برنامه های multi-threading رفتار منظمی رو نمیتونید انتظار داشته باشید.
مثلا این کد رو شما دقیقا کپی کنید و کلاسی به اسم MyTimer براش بسازید و ران کنید ببینید خروجی چی میشه :

package main;

import java.util.Timer;
import java.util.TimerTask;

public class MyTimer {

public int count;
Timer timer;
ToDo todo;

public MyTimer() {
count = 0;
timer = new Timer();
todo = new ToDo();
timer.schedule(todo, 0, 1000);
}

public static void main(String[] args) throws InterruptedException {
new MyTimer();
for(int i=0;i<10;i++){
System.out.print("salam \n");
}
}

class ToDo extends TimerTask {

int count = 0;

public void run() {
{
System.out.println("Task scheduled." + count);
count++;
if (count > 5) {
timer.cancel();
}

}
}
}
}


خروجی های من هر بار متفاوت بود.
این سه خروجی متفاوتی که من گرفتم :
خروجی 1 :


Task scheduled.0
salam
salam
salam
salam
salam
salam
salam
salam
salam
salam
Task scheduled.1
Task scheduled.2
Task scheduled.3
Task scheduled.4
Task scheduled.5


خروجی 2 :


salam
salam
salam
salam
salam
salam
salam
salam
salam
salam
Task scheduled.0
Task scheduled.1
Task scheduled.2
Task scheduled.3
Task scheduled.4
Task scheduled.5


خروجی 3 :


salam
salam
salam
salam
salam
Task scheduled.0
salam
salam
salam
salam
salam
Task scheduled.1
Task scheduled.2
Task scheduled.3
Task scheduled.4
Task scheduled.5


میبینید که در اولین گام که در تایمر هیچ تاخیری نداریم، شروع ها متفاوت است. کلا Thread ها به صورت بی نظم با هم اجرا میشن. ولی اگر در یک Thread تاخیر باشه یعنی اینطوری :

public static void main(String[] args) throws InterruptedException {
new MyTimer();
Thread.sleep(0,1);
System.out.print("salam \n");
}


خروجی همواره :


Task scheduled.0
salam
Task scheduled.1
Task scheduled.2
Task scheduled.3
Task scheduled.4
Task scheduled.5

چون این تاخیر زمان زیادیه و باعث میشه هر Thread حداقل بتونه یه دستورش رو اجرا کنه.که در Timer اولین Task رو اجرا میکنه و در main هنوز در حال اجرای تاخیر است.

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