了解EDT和共享对象?

时间:2013-11-25 20:06:17

标签: java multithreading event-dispatch-thread

您好我正在尝试理解EDT与多线程,希望如果没有意义,有人可以纠正我。

首先,我将GUI的创建过程放在自己的线程中 然后加入EDT

public class Main 
{
static ServerGui serverGui;
public static void main(String[] args)  {
    SwingUtilities.invokeLater(new Runnable()  {
        public void run()   {
            try{
                serverGui = new ServerGui();
                serverGui.frame.setVisible(true);
            }
            catch(Exception e)
            {
                e.printStackTrace();    }} });}}

在我的GUI中,我创建了ServerDataHandler对象sdh

public class ServerGui {
public ServerDataHandler sdh = new ServerDataHandler();

public JFrame frame;

public ServerGui() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {
    frame = new JFrame();
    frame.setType(Type.NORMAL);
    frame.setBounds(100, 100, 800, 600); }  }

现在从另一个线程,我希望使用该sdh对象,并使用一些方法 它有..例如sdh.writeToFile();所以这是我的问题

  1. 因为我想使用同一个对象,我需要这样做,就像我在下面一样吗?。

  2. 我是否需要同步ServerDataHandler类,例如在我的情况下,该方法写入文件?我怀疑我做了

  3. 我什么时候需要使用'invokeLater'?就在我正在改变实际的GUI时?

  4. 客户

    public class Client implements Runnable {
    
    private Socket clientSocket;
    
    public Client(Socket clientSocket) {
        this.clientSocket = clientSocket;
    
    @Override
    public void run() {
        Main.serverGui.sdh.writeToFile();} }
    

1 个答案:

答案 0 :(得分:0)

类和对象

您创建的Main,Client,ServerGui和ServerDataHandler类就是那些类。当您调用类的构造函数时,您将创建一个对象,该对象是该类的实例。

每个线程在JVM中的对象之间编织,遵循执行路径,因为一个对象中的方法调用另一个对象中的方法。所以对象只是放在JVM中,而不是专门绑定到线程。

<强>线程

在JVM里面还有多个线程。您可以使用java.lang.Thread类中的方法自行创建和销毁它们。但主线程和事件调度线程是为您创建的。

可以在一个线程中创建一个Runnable类实例的对象,然后将其移交给另一个线程运行。这是您拨打SwingUtilities.invokeLater时的操作。您创建一个匿名Runnable对象并安排其事件调度线程调用其run()方法。

事件调度线程

这样做的原因是Swing对象不是线程安全的,即一次写入不被多个线程处理。像setVisible(true)这样的方法应该由Event Dispatch Thread调用,一次一个。

将在Event Dispatch Thread上调用分配给Swing对象的侦听器中的事件处理方法。当他们被调用时,事件调度线程正在忙着编织事件处理程序代码,并且无法在屏幕上绘制像素或对按钮点击作出反应。因此,如果您希望用户界面具有响应性,则应保持事件处理代码的简短快捷。

如果要运行冗长的任务,例如读取长文件或与服务器聊天,则应创建并启动新线程以运行此任务。这称为后台或工作线程。您可以为要运行的作业创建Runnable类,并将其提供给您创建的Thread。

一种更高级的计划任务方法是通过java.util.concurrent包中的类,特别是ExecutorService。

包含更多信息的好教程是Concurrency in Swing