简体   繁体   English

将对象传递到另一个线程

[英]passing objects to another thread

i am creating a GUI application and in the background I want to run an additional task. 我正在创建一个GUI应用程序,并且在后台我想运行其他任务。 I will paste some code, to prevent pasting a mess of code that was generated by Swing, I will leave some parts out, assume that the window.java is working as intended. 我将粘贴一些代码,以防止粘贴由Swing生成的一堆代码,假设window.java可以正常工作,我将省略一些部分。

window.java: window.java:

public class window {
frame = new JFrame();
JLabel lbl1 = new JLabel("Start Counter");
frame.add(lbl1);

Thread counter = new Thread(new counter());
    counter.start();
}

counter.java counter.java

public class regCheck extends window implements Runnable
{

public void run()
{
    int i = 0;
    while (true)
    {
        window.lbl1.setText(i);
        try {Thread.sleep(1000);}
            catch (InterruptedException e) {e.printStackTrace();}
        i++;
    }
}
}

what I want this example to do is create a label within a window and count upwards until the program is closed. 我希望本示例执行的操作是在窗口中创建标签,然后向上计数直到关闭程序。 The easy answer here is to say "pass in the Jlabel" however in reality I have multiple things that I need to change not just a label. 此处的简单答案是说“传递Jlabel”,但实际上,我有很多需要更改的内容,而不仅仅是标签。

the line "window.lbl1.setText(i);" 行“ window.lbl1.setText(i);” does not work here, it is just to illustrate what I want to achieve. 在这里不起作用,只是为了说明我想要实现的目标。

Use the MVC pattern. 使用MVC模式。 Create a model that has the counter with a setValue() method that fires a listener notification. 创建一个具有带有setValue()方法的计数器的模型,该方法将触发侦听器通知。 You can extend java.util.Observable to make that easier to do. 您可以扩展java.util.Observable使其更容易实现。 Add a getValue() method to retrieve the new count. 添加一个getValue()方法以检索新计数。 Make the setter and getter synchronized for thread safety. 使设置程序和吸气剂同步以确保线程安全。

Now your thread can be passed an instance of the model and call setValue() to update the value in its run() method. 现在,您的线程可以被传递给模型的实例,并调用setValue()来更新其run()方法中的值。

Finally, your view can be passed the same instance of the model and add a listener to it. 最后,您的视图可以传递给模型的相同实例,并向其添加侦听器。 To make it easier your view can implement java.util.Observer . 为了简化操作,您的视图可以实现java.util.Observer In the listener update() callback within the view, call the model's getValue() and use the return as the argument to setText() . 在视图中的侦听器update()回调中,调用模型的getValue()并将return用作setText()的参数。 Since the listener update is not being invoked from the AWT event dispatcher thread, you have to call setText() using javax.swing.SwingUtilities.invokeLater() in order to meet the thread safety requirements of Swing. 由于未从AWT事件调度程序线程调用侦听器更新,因此必须使用javax.swing.SwingUtilities.invokeLater()调用setText()才能满足Swing的线程安全要求。

it is actually architectural question, you can pass any arguments to other thread and this thread of course could modify different labels, but I prefer another variant: 这实际上是架构问题,您可以将任何参数传递给其他线程,并且该线程当然可以修改不同的标签,但是我更喜欢另一个变体:

  1. you have window, which has its objects/controls and can manipulate them 您有一个窗口,它具有其对象/控件并可以对其进行操作
  2. you have separate thread which increase counter 你有单独的线程,增加计数器

this separate thread should notify main window object about changes and window object should change it's controls accordingly, for example change text in one or several controls 该单独的线程应通知主窗口对象有关更改,并且窗口对象应相应地更改其控件,例如更改一个或多个控件中的文本

one simple variant is to have interface, like ICounterHandler with one method 一种简单的变体是具有接口,例如具有一种方法的ICounterHandler

void onCounterChanged(int newCounterValue);

counter thread should accept ICounterHandler in constructor, save it and call this method when needed, preferable asynchronous 计数器线程应在构造函数中接受ICounterHandler,将其保存并在需要时调用此方法,最好是异步方法

of course there are many other variants, but you can start with this one 当然,还有许多其他变体,但是您可以从此开始

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM