EDT、异步、同步
EDT, asynchronous, synchronous
从EDT(Event Dispatcher Thread)开始一个新线程时,新线程永远不会是EDT,因为只有一个EDT,对吧?我问是因为我看到一些代码检查 if (!SwingUtils.isDispatcherThread())
,我想知道为什么它需要这个检查?
我的问题是:当启动一个新线程时,是什么让它同步(必须等待新线程完成)或异步(新线程returns 立即完成)?据此如何自己启动一个同步或异步线程?
以下面为例。在 EDT 中启动非 EDT 线程时,如下所示:
public void actionPerformed(final ActionEvent e)
{
final Runnable runnable = new Runnable()
{
@Override
public void run()
{
//do some non-gui task. The task is not long-running, but
//could be blocked
doTask();
}
};
new Thread(runnable).start();
}
});
从 EDT 生成的非 EDT 线程是同步的还是异步的?如果 doTask()
挂起,是否应该阻止 EDT UI?
如果我无法控制doTask()
并且无法更改方法,那么有什么好的方法来处理产生新线程并且新线程可能挂起的情况?在父线程中使用 Thread.join()
?
the new thread will never be EDT, as there is only one EDT, right?
没错。
I am asking as I see some code checks "if (!SwingUtils.isDispatcherThread())", and I wonder why it needs this check?
因为有时可以从 EDT 或后台线程调用方法,并且必须根据当前线程采取不同的操作。
when starting a new thread, what makes it synchronous (has to wait for the new thread to finish) or asynchronous (the new thread returns right away)?
当您启动一个新线程时,新线程总是与生成线程同时运行。除非您明确加入(或使用其他同步机制),否则生成线程永远不会等待生成线程完成。
Should EDT UI be blocked if doTask() hangs?
否,除非生成的线程在保持 EDT 尝试获取的锁时挂起。
If I have no control over doTask() and the method cannot be changed, what is a good way to deal with the situation that spawns a new thread and the new thread might hang? use Thread.join() in parent thread?
那会更糟:现在 EDT 也会挂起,从而完全冻结 UI,直到挂起的线程停止挂起并终止。
如果您有一个挂起的线程,请修复它正在执行的代码,使其不再挂起。如果您无法修复它,请让负责该代码的人来修复它。
- EDT:是的,只有 1 个 EDT。您创建的任何线程都不会是 EDT
- 同步 vs 异步:java 中的
Thread
与其他任何一个 class 一样,但是当您调用 start()
时,它会创建一个新线程来运行run()
方法或在 Runnable.run 方法中,如果 Runnable 是异步提供的。
- 方法可能会阻塞/从不return:关键是使用回调/侦听器...在导致更新的处理过程中的某个时刻调用的方法。没有停止阻塞线程的通用解决方案,但是可以在许多情况下使用的 2 种机制是 (a)InputStream/Reader.close() 如果您正在等待输入流上的数据或 reader,或 (b) Thread.interrupt
从EDT(Event Dispatcher Thread)开始一个新线程时,新线程永远不会是EDT,因为只有一个EDT,对吧?我问是因为我看到一些代码检查 if (!SwingUtils.isDispatcherThread())
,我想知道为什么它需要这个检查?
我的问题是:当启动一个新线程时,是什么让它同步(必须等待新线程完成)或异步(新线程returns 立即完成)?据此如何自己启动一个同步或异步线程?
以下面为例。在 EDT 中启动非 EDT 线程时,如下所示:
public void actionPerformed(final ActionEvent e)
{
final Runnable runnable = new Runnable()
{
@Override
public void run()
{
//do some non-gui task. The task is not long-running, but
//could be blocked
doTask();
}
};
new Thread(runnable).start();
}
});
从 EDT 生成的非 EDT 线程是同步的还是异步的?如果 doTask()
挂起,是否应该阻止 EDT UI?
如果我无法控制doTask()
并且无法更改方法,那么有什么好的方法来处理产生新线程并且新线程可能挂起的情况?在父线程中使用 Thread.join()
?
the new thread will never be EDT, as there is only one EDT, right?
没错。
I am asking as I see some code checks "if (!SwingUtils.isDispatcherThread())", and I wonder why it needs this check?
因为有时可以从 EDT 或后台线程调用方法,并且必须根据当前线程采取不同的操作。
when starting a new thread, what makes it synchronous (has to wait for the new thread to finish) or asynchronous (the new thread returns right away)?
当您启动一个新线程时,新线程总是与生成线程同时运行。除非您明确加入(或使用其他同步机制),否则生成线程永远不会等待生成线程完成。
Should EDT UI be blocked if doTask() hangs?
否,除非生成的线程在保持 EDT 尝试获取的锁时挂起。
If I have no control over doTask() and the method cannot be changed, what is a good way to deal with the situation that spawns a new thread and the new thread might hang? use Thread.join() in parent thread?
那会更糟:现在 EDT 也会挂起,从而完全冻结 UI,直到挂起的线程停止挂起并终止。
如果您有一个挂起的线程,请修复它正在执行的代码,使其不再挂起。如果您无法修复它,请让负责该代码的人来修复它。
- EDT:是的,只有 1 个 EDT。您创建的任何线程都不会是 EDT
- 同步 vs 异步:java 中的
Thread
与其他任何一个 class 一样,但是当您调用start()
时,它会创建一个新线程来运行run()
方法或在 Runnable.run 方法中,如果 Runnable 是异步提供的。 - 方法可能会阻塞/从不return:关键是使用回调/侦听器...在导致更新的处理过程中的某个时刻调用的方法。没有停止阻塞线程的通用解决方案,但是可以在许多情况下使用的 2 种机制是 (a)InputStream/Reader.close() 如果您正在等待输入流上的数据或 reader,或 (b) Thread.interrupt