Tag: multithreading

为什么人们在事件队列上运行Java GUI

在Java中,要创建并显示一个新的JFrame ,我只需这样做: public static void main(String[] args) { new MyCustomFrameClass().setVisible(true); } 但是,我见过很多人这样做: public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { new MyCustomFrameClass().setVisible(true); } }); } 为什么? 有什么好处吗?

如何确保我不是同时在两个线程之间共享相同的套接字?

我有一个代码,我正在处理套接字,我需要确保我不在两个线程之间共享相同的套接字 。 在我的下面的代码中,我有一个后台线程,每60秒运行一次并调用updateLiveSockets()方法。 在updateLiveSockets()方法中,我迭代我拥有的所有套接字,然后通过调用SendToQueue类的send方法SendToQueue ping它们,并根据响应我将它们标记为活动或死亡。 现在所有的读者线程将同时调用getNextSocket()方法来获取下一个可用的套接字,因此它必须是线程安全的,我需要确保所有的读者线程都应该看到相同的SocketHolder和Socket状态。 下面是我的SocketManager类: public class SocketManager { private static final Random random = new Random(); private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); private final Map<Datacenters, List> liveSocketsByDatacenter = new ConcurrentHashMap(); private final ZContext ctx = new ZContext(); // … private SocketManager() { connectToZMQSockets(); scheduler.scheduleAtFixedRate(this::updateLiveSockets, 60, 60, TimeUnit.SECONDS); } // during startup, making […]

Java Shutdown挂钩未运行

我是Java / threads的新手,我inheritance了类似下面的代码。 它是一个命令行程序,main()只启动5-6种不同类型的线程,并以^ C退出。 我想添加一个关闭钩子来正确关闭所有线程并按以下方式调整它。 我在所有线程中添加了一个Shutdown钩子和一个stopThread()方法(比如MyWorker类中的那个) 问题是,当我按^ CI时,看不到Thread的run方法中的结束消息。 这是在后台完成还是我的方法有问题。 另外,我应该遵循更好的模式吗? 谢谢 public class Main { public static MyWorker worker1 = new MyWorker(); // .. various other threads here public static void startThreads() { worker1.start(); // .. start other threads } public static void stopThreads() { worker1.stopThread(); // .. stop other threads } public static […]

JavaFX SwingWorker等效?

JavaFX是否与Java SwingWorker类等效? 我知道JavaFX 任务,但你只能发布字符串消息或进度。 我只想在GUI线程中调用一个方法,就像我对SwingWorker一样(通过发布任意类型的消息)。 赫雷斯是我的意思的一个例子: class PrimeNumbersTask extends SwingWorker<List, Integer> { PrimeNumbersTask(JTextArea textArea, int numbersToFind) { //initialize } @Override public List doInBackground() { while (! enough && ! isCancelled()) { number = nextPrimeNumber(); publish(number); setProgress(100 * numbers.size() / numbersToFind); } } return numbers; } @Override protected void process(List chunks) { for (int number : […]

如何编写JUnit测试用例来测试线程和事件

我有一个在一个(主)线程中工作的java代码。 从主线程,我产生一个新线程,我在其中进行服务器调用。 服务器调用完成后,我在新线程中做了一些工作,然后代码加入主线程。 我正在使用eclipse Jobs来进行服务器调用。 我想知道,我如何为此编写一个JUnit测试用例。

使用Runtime.exec()生成的进程的高效执行和输出流重定向

我有一个脚本,它执行多次程序,为STDERR和STDOUT产生大约350行输出。 现在,我需要在Java中执行脚本,从而将输出流打印到其原始目标。 所以,基本上,我从Java类中执行脚本,维护用户的原始行为。 我这样做的方式受到了诸如从java Runtime.exec读取流的建议的启发,并且在function上,工作正常。 Process p = Runtime.getRuntime().exec(cmdarray); new Thread(new ProcessInputStreamHandler(p.getInputStream(), System.out)).start(); new Thread(new ProcessInputStreamHandler(p.getErrorStream(), System.err)).start(); return p.waitFor(); 而ProcessInputStreamHandler类: class ProcessInputStreamHandler implements Runnable { private BufferedReader in_reader; private PrintStream out_stream; public ProcessInputStreamHandler(final InputStream in_stream, final PrintStream out_stream) { this.in_reader = new BufferedReader(new InputStreamReader(in_stream)); this.out_stream = out_stream; } @Override public void run() { String line; […]

CopyOnWriteArrayList抛出CurrentModificationException

当我遍历列表时,我偶尔会得到一个ConcurrentModificationException 。 谷歌搜索告诉我,这可能是因为我在迭代它时在另一个线程中改变该列表并且为了使这个问题消失我应该使用java.util.concurrent.CopyOnWriteArrayList …. ……除了我已经是。 显然,我正在做一些非常愚蠢的事情。 有没有人知道如何诱使CopyOnWriteArrayList抛出ConcurrentModificationException ? 如果重要,我正在使用Java 5。 编辑:由于我正在使用的mutators可能很重要,我正在以两种方式修改此列表: 在前面添加元素。 ( list.add(0, newElement); ) 使用subList让旧项目脱落。 ( list = list.subList(0, MAX_LIST_SIZE); ) 那些举起红旗吗? 如果是这样,为什么? 我的理解是,因为这些操作首先复制了这个东西,所以任何现有的迭代器都会指向未经修改的原始文件,因此不关心。 我的知识是否有漏洞? 编辑2:导致问题的确切代码仍然有点模糊,但我至少可以发布我看到的exception: java.util.ConcurrentModificationException at java.util.concurrent.CopyOnWriteArrayList$COWSubList.checkForComodification(Unknown Source) at java.util.concurrent.CopyOnWriteArrayList$COWSubList.iterator(Unknown Source) at…. …它指向我的代码中的for-each循环实例化。 那个COWSubList似乎暗示我对subList调用是我问题的根源; 我还是想明白为什么。 编辑3: * facepalm * CopyOnWriteArrayList.subList()返回List , 而不是 CopyOnWriteArrayList 。 它返回的清单没有提供任何COWAL保护的隐含义务。 这使得使用像这样的subList()来删除一个非常不好的想法。 不确定这是否是我的罪魁祸首,但它是可疑的,无论如何都需要纠正。

在ThreadPoolExecutor中使用InheritableThreadLocal – 或者 – 不重用线程的ThreadPoolExecutor

我试图使用InheritableThreadLocal和ThreadPoolExecutor 。 这会分解,因为ThreadPoolExecutor为每个池重用线程(毕竟它是一个池),这意味着InheritableThreadLocal不能按预期工作。 现在这个问题对我来说显而易见,但追踪却特别狡猾。 我使用InheritableThreadLocal以便几个顶级进程中的每一个都有自己的数据库连接以及它产生的任何子进程。 我不只是使用一个共享连接池,因为每个顶级进程在提交到数据库和/或准备大量反复使用的PreparedStatements之前,将使用其连接进行大量的多步骤工作。 我在这些顶级进程之间使用共享的ThreadPoolExecutor ,因为某些行为需要被门控。 虽然我可能有4个顶级进程在运行,但我一次只能有一个进程写入数据库(或者系统需要访问其他一些共享资源)。 因此,我将让顶级进程创建一个Runnable并将其发送到共享的ThreadPoolExecutor ,以确保在整个系统中同时运行不超过一个(或两个或三个)。 问题是因为ThreadPoolExecutor重用其池的线程,所以InheritableThreadLocal将获取在该池中运行的原始值,而不是将Runnable发送到ThreadPoolExecutor的顶级进程中的值。 有没有办法强制ThreadPoolExecutor的工作池使用创建Runnable而不是在重用线程池的上下文中的进程上下文中的InheritableThreadLocal值? 或者,是否有任何ThreadPoolExecutor实现,每次启动一个新的Runnable时都会创建一个新线程? 出于我的目的,我只关心将同时运行的线程的数量设置为固定大小。 有没有其他解决方案或建议人们让我完成我上面描述的内容? (虽然我意识到我可以通过将类数据库连接从类传递到子线程到子线程来解决问题,就像某种社区自行车一样,我想避免这种情况。) 还有一个关于StackOverflow, InheritableThreadLocal和线程池的问题也解决了这个问题。 但是,该问题的解决方案似乎是它对于InheritableThreadLocal来说是一个糟糕的用例,我不认为这适用于我的情况。 谢谢你的任何想法。

如何在Java中实现多个线程来下载单个表数据?

如何实现具有多个/相同连接的多个线程,以便可以快速下载单个大型表数据。 实际上在我的应用程序中,我正在下载一个有12个lacs(1 lac = 100,000)记录的表,这个记录至少需要4小时才能以正常的连接速度下载,而更多的hrs连接速度慢。 因此,需要在Java中实现多个线程,用于下载具有多个/相同连接对象的单个表数据。 但不知道该怎么做。 如何在多个线程中定位记录指针然后如何将所有线程记录添加到单个大文件中? 提前致谢

制作一个显示“请等待”JDialog的摇摆线程

问题是这样的: 我正在运行一个swing应用程序,在某个时刻,对话框需要插入用户名和密码并按“确定”。 我希望当用户按“确定”时,swing应用程序按此顺序执行: 打开“请等待”JDialog 进行一些操作(最终显示其他一些JDialog或JOptionPane) 当它完成操作时关闭“请等待”JDialog 这是我在okButtonActionPerformed()中编写的代码: private void okButtonActionPerformed(java.awt.event.ActionEvent evt) { //This class simply extends a JDialog and contains an image and a jlabel (Please wait) final WaitDialog waitDialog = new WaitDialog(new javax.swing.JFrame(), false); waitDialog.setVisible(true); … //Do some operation (eventually show other JDialogs or JOptionPanes) waitDialog.dispose() } 这段代码显然不起作用,因为当我在同一个线程中调用waitDialog时,它会阻塞所有代码直到我不关闭它。 所以我试着在另一个线程中运行它: private void okButtonActionPerformed(java.awt.event.ActionEvent evt) { […]