从 ActionPerformed 调用方法并在主线程上 运行 它
Calling a method from ActionPerformed and running it on main thread
我的程序 UI 在按下 JButton 后冻结了一段时间。我发现造成这种情况的原因是信号量阻塞了 Swing 线程。这是包含对信号量的 acquire()
调用的方法:
private void fetch(int numThreads) {
//some code here
sem = new Semaphore(numThreads);
for (int i = 0; i < model.getRowCount(); i++){
try {
sem.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
//some code here
}
这是唯一调用 fetch()
的方法
concFetchButt.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
switchButtonStates(false);
}
});
fetch(Integer.parseInt(threadsNumField.getText()));
}
据我了解,此代码最终在 Swing 线程上 运行ning fetch()
,但据推测它与 Swing 无关。
我想,我的问题是这样的:如何在程序的主线程而不是 Swing 线程上 运行 从 Swing 的 'ActionPerformed()' 调用的方法?
无需在 "main" 线程上专门 运行。只需 运行 它在 任何 其他线程上,但 Swing UI 线程。
最简单的解决方案:
- 将 ExecutorService 添加到您的 class
- 将该代码
fetch(Integer.parseInt(threadsNumField.getText()));
放入 Runnable 对象中
- 将 Runnable 提交给 ExecutorService
按照:
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
public void run() {
fetch(Integer.parseInt(threadsNumField.getText()));
}
});
我的程序 UI 在按下 JButton 后冻结了一段时间。我发现造成这种情况的原因是信号量阻塞了 Swing 线程。这是包含对信号量的 acquire()
调用的方法:
private void fetch(int numThreads) {
//some code here
sem = new Semaphore(numThreads);
for (int i = 0; i < model.getRowCount(); i++){
try {
sem.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
//some code here
}
这是唯一调用 fetch()
concFetchButt.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
switchButtonStates(false);
}
});
fetch(Integer.parseInt(threadsNumField.getText()));
}
据我了解,此代码最终在 Swing 线程上 运行ning fetch()
,但据推测它与 Swing 无关。
我想,我的问题是这样的:如何在程序的主线程而不是 Swing 线程上 运行 从 Swing 的 'ActionPerformed()' 调用的方法?
无需在 "main" 线程上专门 运行。只需 运行 它在 任何 其他线程上,但 Swing UI 线程。
最简单的解决方案:
- 将 ExecutorService 添加到您的 class
- 将该代码
fetch(Integer.parseInt(threadsNumField.getText()));
放入 Runnable 对象中 - 将 Runnable 提交给 ExecutorService
按照:
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
public void run() {
fetch(Integer.parseInt(threadsNumField.getText()));
}
});