ورود

View Full Version : سوال: MultiThreading و اینترفیس Runnable برای یک کلاس به زبان ساده؟



vahid-p
یک شنبه 15 اردیبهشت 1392, 18:22 عصر
سلام دوستان
میخوام یک کلاس بسازم که خودش ساب کلاس یه چیزی مثل JFrame باشه و از طرفی بتونیم برنامه رو چند نخی ( MultiThreading ) کنیم، که برای پیاده سازیش مشکل دارم.

من اول دیدم اینجوری بنویسم، باعث میشه متد start رو نداشته باشیم :
public class MyClass extends JFrame implements Runnable

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

spiderman200700
یک شنبه 15 اردیبهشت 1392, 19:53 عصر
من اول دیدم اینجوری بنویسم، باعث میشه متد start رو نداشته باشیم :
public class MyClass extends JFrame implements Runnable

چرا باعث میشه متد start رو نداشته باشیم؟

خب اگه با MultiThreading آشنا باشی خیلی راحت میتونی این کار رو انجام بدی. هر جا که خواستی کدت رو موازی اجرا کنی ، یه Thread بساز و اجراش کن.
اینم یه مثال:
Thread t=new Thread(new Runnable() {

public void run() {
//your balance code
}
});
t.start();

vahid-p
یک شنبه 15 اردیبهشت 1392, 23:42 عصر
خب همون دیگه آشنا نیستم.
میشه مثالتون طبق اون چیزی که گفتم باشه؟
منظورم اینه که اگه کلاسمون به اون صورت که بالا هست تعریف کنیم بعدا اگه بنویسیم :
MyClass first=new MyClass();
first.start();
اینجا start که نوشتم وجود نداره.
اینی که شما نوشتید که خود Thread نیو شده. در صورتی که ما میخواهیم کلاسی که ساب کلاس یه چیزی غیر از Thread هست رو نیو کنیم و در اون run رو داشته باشیم از طرفی بشه با start اونو شروع کنیم. ولی اگه مثلا اینجا بنویسیم first.run که مثل متد معمولی باهاش برخورد میشه و موازی بقیه آبجکتها اجرا نمیشه!

فکر کنم تمامی مفاهیم رو قاطی کردم!!!!!!!

vahid-p
دوشنبه 16 اردیبهشت 1392, 01:40 صبح
بلاخره به جواب رسیدم! :بوس::لبخند:

مشکل من این بود که هنوز مفهوم Interface رو دقیق دقیق نفهمیده بودم با اینکه ازش استفاده میکردم و با ActionListener که یک اینترفیس دیگست و مثال دوست عزیز spiderman200700 (http://barnamenevis.org/member.php?133001-spiderman200700) که new Runnable کرده بودن جرقه ای خورد تا به جواب برسم.
گفتم اگه سوال کس دیگه ای باشه و از اونجا که منابع جاوا به زبان فارسی کمه، شاید اینی که مینویسم یه روزی به درد یکی بخوره!
در اصل Interface ای که Runnable باشه اینجا میاد MyFrame که ساب کلاس JFrame هست رو بتوان به صورت Runnable در کانستراکتور Thread استفاده کرد.

خب کل اینا یعنی چی؟
ما برای ساختن هر Thread میتونیم مستقیما از خود Thread استفاده کنیم یا ساب کلاسی که براش ساختیم. اما چون اینجا MyFrame ساب کلاس JFrame هست پس نمیتونه ساب کلاس Thread هم باشه. پس مستقیما از خودش استفاده میکنیم یا تو یه کلاس دیگه ساب کلاسش درست میکنیم که نیازی نیست.
پس اول کلاس MyFrame رو می نویسیم :
MyFrame.java
package prog;
import javax.swing.JFrame;

public class MyFrame extends JFrame implements Runnable{
int delay;
public MyFrame(int delay)
{
this.delay=delay;
setSize(200,200);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}

@Override
public void run() {
try {
for(int i=0;i<100;i++){
setTitle("Title #"+i);
Thread.sleep(delay);
}
} catch (InterruptedException ex) {
System.err.println(ex);
}
}
}

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

حالا کلاس اصلی.
Main.java
package prog;

public class Main {

public static void main(String[] args) {
MyFrame win1=new MyFrame(1000);
MyFrame win2=new MyFrame(500);
win2.setLocation(300, 0);

Thread t1=new Thread(win1);
Thread t2=new Thread(win2);

t1.start();
t2.start();
}
}
خب اینجا دو فریم ساختیم ( چون خودشون ساب کلاسی از JFrame هستند پس میشه اونا رو به عنوان آبجکت ساخت )
بعد دو تا Thread ساختیم که در کانستاکتورش که به صورت
public Thread(Runnable target)
هست برای آرگومان اولی میایم و همون فریم های قبلی که اسمشون win1 و win2 هست رو قرار میدیم. ( چون از اینترفیس Runnable هست پس میشه قرار داد )
و اون Thread ها رو start میکنیم تا از run پیاده سازی شده و override شده در MyFrame استفاده کنه.
این کد ها رو تو دو فایل به اسمهای MyFrame.java و Main.java و در پکیج prog کپی کنید تا خروجی رو ببینید.

younes221
دوشنبه 16 اردیبهشت 1392, 16:35 عصر
سلام ؛ میتونستید به شکل زیر هم بنویسید :

import javax.swing.JFrame;
import javax.swing.JOptionPane;

/**
*
* @author aa
*/
public class ThreadingExample extends JFrame implements Runnable{

private int _dealy;
private Thread _thread;

public ThreadingExample(int delay){
this._dealy = delay;
this._thread = new Thread(this, "SubThread");
super.setDefaultCloseOperation(EXIT_ON_CLOSE);
super.setSize(400, 400);
super.setVisible(Boolean.TRUE);
}

@Override
public void run() {
try{
for(int counter=0;counter<100;counter++){
super.setTitle(String.valueOf(counter));
Thread.sleep(this._dealy);
}
}catch(InterruptedException e1){
JOptionPane.showMessageDialog(null, e1.getMessage());
}
}

public void start(){
this._thread.start();
}

public static void main(String[] args){
ThreadingExample thread1 = new ThreadingExample(1000);
ThreadingExample thread2 = new ThreadingExample(2000);
thread1.start();
thread2.start();
}

vahid-p
دوشنبه 16 اردیبهشت 1392, 19:31 عصر
آره اینی که شما گفتید فکر کنم بیشتر به کار بیاد. فکر کنم وقتی بخوایم چندین پنل تو یه JFrame داشته باشیم از این برای هر پنل استفاده کنیم بهتر باشه.

به هر حال ممنون از شما