gpt4 book ai didi

java - 使用 CachedThreadPool 写入 JTextArea

转载 作者:行者123 更新时间:2023-11-30 03:24:39 24 4
gpt4 key购买 nike

我在 CodeReview 中问过这个问题,但它已关闭。

对于一项学校作业,我必须创建 54 个从 Executors.newCachedThreadPool() 同时运行的线程。写入 JTextArea以线程安全的方式。每个线程必须将“A”到“Z”写入该字段 1000 次。无论我将 synchronized 放在哪里,我都遇到了使程序线程安全的问题。关键词。我有一个可运行的类来进行编写,但我在保持线程安全方面遇到了问题。我尝试过的唯一有效的方法是输入 Thread.sleep(500)在循环遍历所有字母的循环中,当我增加迭代次数时,它不起作用,并且无论如何都会在 Netbeans 中发出警告。

将把synchronized关键字在正确的位置使线程安全,还是我必须更改线程本身?我在下面的评论中留下了我之前的一些尝试。

我更改了代码,使其可以运行一次。它运行一个写入 JTextArea 的实例。但我在将其转变为多个同步线程时遇到问题。

AlphabetThread.java

package threadpool;

import javax.swing.JTextArea;

public class AlphabetThread implements Runnable{

char letter;
JTextArea toEdit;
//final int NUMBER_OF_ITERATIONS = 1000;

public AlphabetThread(char e, JTextArea tf) {
letter = e;
toEdit = tf;
}

@Override
public void run() {
//for (int i = 0; i < NUMBER_OF_ITERATIONS; i++) {

toEdit.setText(toEdit.getText() + letter);

}

// public synchronized void createThread() {
// for (int i = 0; i < NUMBER_OF_ITERATIONS; i++) {
//
// toEdit.setText(toEdit.getText() + letter);
// }
// }
}

ThreadPool.java

package threadpool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPool {

// static char letter;
//
// Thread alphabetThread = new Thread(() -> {
// char e = letter;
// mainWindow.textBox.setText(mainWindow.textBox.getText() + e);
// });
// public static synchronized AlphabetThread createThread(char e, JTextArea tf) throws InterruptedException {
// AlphabetThread runMe = new AlphabetThread(e, tf);
// return runMe;
// }
public static void main(String[] args) {
TextWindow mainWindow = new TextWindow();
ExecutorService pool = Executors.newCachedThreadPool();

for (char alphabet = 'A'; alphabet <= 'Z'; alphabet++) {

AlphabetThread alphabetThread = new AlphabetThread(alphabet, mainWindow.textBox);
alphabetThread.run();

}
pool.shutdown();
}
}

TextWindow.java

package threadpool;

import java.awt.Dimension;
import java.awt.HeadlessException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class TextWindow extends JFrame {

public JPanel mainPanel = new JPanel();
public JTextArea textBox = new JTextArea();

public TextWindow() throws HeadlessException {

add(mainPanel);
textBox.setPreferredSize(new Dimension(450,450));
textBox.setVisible(true);
mainPanel.add(textBox);
setVisible(true);
setSize(500, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
pack();
}

}

完整的解决方案不是必需的(尽管它会很好)。我更喜欢一些关于在哪里更正代码的指示。

最佳答案

您的代码存在一些问题。首先,一般规则是您需要对所有线程使用相同监视对象进行同步。此外,您的尝试似乎是同步创建线程,而不是在写入文本区域时。 如果 swing 是线程安全的,您可以使用文本区域作为监视对象,例如:

synchronized (toEdit) {
toEdit.setText(toEdit.getText() + letter);
}

这足以同步写入。然而,swing 不是线程安全的。这是第二个问题。修改 JComponents 必须仅在事件分派(dispatch)线程中完成。这是使用 invokeLater() 完成的或(很少)invokeAndWait():

SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
toEdit.setText(toEdit.getText() + letter);
}
}

这也意味着所有的写入请求都会排队,您无需再担心写入部分的线程安全问题。

关于java - 使用 CachedThreadPool 写入 JTextArea,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30561744/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com