《Java Concurrency in Practice》ch9 GUI Applications

原创 2012年03月21日 22:00:20

1. EDT (Event Dispatch Thread)

Question: Why are GUIs Single-threaded?

1) 不要再EDT执行时间较长的任务,否则GUI无法及时响应。

2) SwingUtilities.invokeLater() 可以将一个Runnable任务调度到事件线程中执行(可以在任意线程中调用)

2. 短时间的GUI任务

在EDT中处理

3. 长时间的GUI任务

使用SwingWorker,支持取消、进度标识和完成标识(可以考虑用于改正以前的假进度条了)。

下面是一个demo,from http://www.java2s.com/Code/Java/JDK-6/SwingWorkerfromJDK6SE.htm

import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;

public class SwingWorkerDemo {
	public static void main(String[] args) {
		JTextArea textArea = new JTextArea(10, 20);
		final JProgressBar progressBar = new JProgressBar(0, 10);

		final CounterTask task = new CounterTask();
		task.addPropertyChangeListener(new PropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent evt) {
				if ("progress".equals(evt.getPropertyName())) {
					progressBar.setValue((Integer) evt.getNewValue());
				}
			}
		});
		JButton startButton = new JButton("Start");
		startButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				task.execute();
			}
		});

		JButton cancelButton = new JButton("Cancel");
		cancelButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				task.cancel(true);
			}
		});

		JPanel buttonPanel = new JPanel();
		buttonPanel.add(startButton);
		buttonPanel.add(cancelButton);

		JPanel cp = new JPanel();
		LayoutManager layout = new BoxLayout(cp, BoxLayout.Y_AXIS);
		cp.setLayout(layout);
		cp.add(buttonPanel);
		cp.add(new JScrollPane(textArea));
		cp.add(progressBar);

		JFrame frame = new JFrame("SwingWorker Demo");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setContentPane(cp);
		frame.pack();
		frame.setVisible(true);
	}
}

class CounterTask extends SwingWorker<Integer, Integer> {
	private static final int DELAY = 1000;

	public CounterTask() {
	}

	@Override
	protected Integer doInBackground() throws Exception {
		int i = 0;
		int count = 10;
		while (!isCancelled() && i < count) {
			i++;
			publish(new Integer[] { i });
			setProgress(count * i / count);
			Thread.sleep(DELAY);
		}

		return count;
	}

	protected void process(List<Integer> chunks) {
		System.out.println("process : " + Thread.currentThread().getName());
		for (int i : chunks)
			System.out.println(i);
	}

	@Override
	protected void done() {
		System.out.println("done : " + Thread.currentThread().getName());
		if (isCancelled())
			System.out.println("Cancelled !");
		else
			System.out.println("Done !");
	}
}

运行结果:


process : AWT-EventQueue-0
1
process : AWT-EventQueue-0
2
process : AWT-EventQueue-0
3
process : AWT-EventQueue-0
4
process : AWT-EventQueue-0
5
process : AWT-EventQueue-0
6
process : AWT-EventQueue-0
7
process : AWT-EventQueue-0
8
process : AWT-EventQueue-0
9
process : AWT-EventQueue-0
10
done : AWT-EventQueue-0
Done !


可以看出,progress(在事件指派线程 上异步地从 publish 方法接收数据块)方法果然是被EDT线程调度的。

相关文章推荐

《Java Concurrency in Practice》ch6 Task Execution

3个notes, 1. don't use Thread, use Executor Executor may be a simple interface, but it forms the ba...
  • nomad2
  • nomad2
  • 2012年03月20日 21:28
  • 559

《Java Concurrency in Practice》ch11 Performance and Scalability

1. 没有免费的午餐 While the goal may be to improve performance overall, using multiple threads always intr...
  • nomad2
  • nomad2
  • 2012年03月21日 22:26
  • 437

《Java Concurrency in Practice》中文版笔记

第1章 简介1.1 并发简史 茶壶和面包机的生产商都很清楚:用户通常会采用异步方式来使用他们的产品,因此当这些机器完成任务时都会发出声音提示。 1.2 线程的优势 线程能够将大部分的异步工作流转换成串...

[Java Concurrency in Practice]第八章 线程池的使用

线程池的使用8.1 在任务与执行策略之间的隐性耦合虽然Executor框架为制定和修改执行策略提供了相当大的灵活性,但并非所有的任务都能适用所有的执行策略。有些类型的任务需要明确地执行执行策略,包括:...

Java Concurrency in Practice读书笔记

java concurrency in practice.pdf 2014-12-04 23:19:11 Effectively immutable objects must be safel...

《Java Concurrency in Practice》之加锁机制(Locking)

@NotThreadSafe public class UnsafeCachingFactorizer extends HttpServlet { private static final lon...

[Java Concurrency in Practice]第十二章 并发程序的测试

并发程序的测试在测试并发程序时,所面临的主要挑战在于:潜在错误的发生并不具有确定性,而是随机的。要在测试中将这些故障暴露出来,就需要比普通的串行程序测试覆盖更广的范围并且执行更长的时间。在进行安全性测...

[Java Concurrency in Practice]第四章 对象的组合

对象的组合我们并不希望每一次内存访问都进行分析以确保程序时线程安全的,而是希望将一些现有的线程安全组件组合为更大规模的组件或程序。本章将介绍一些组合模式,这些模式能够将一个类更容易成为线程安全的,并且...

[Java Concurrency in Practice]第三章 对象的共享

对象的共享第二章介绍了如何通过同步来避免多个线程在同一时刻访问相同的数据,而第三章则介绍如何共享和发布对象,从而使它们能够安全地由多个线程同时访问。这两章合在一起就形成了构建线程安全类以及通过java...

java concurrency in practice - 1

In early timesharing systems, each process was a virtual von Neumann computer; it had a memory space...
  • G_rrrr
  • G_rrrr
  • 2012年05月22日 10:56
  • 358
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:《Java Concurrency in Practice》ch9 GUI Applications
举报原因:
原因补充:

(最多只允许输入30个字)