《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 阅读笔记(第一、二部分)

第一章:简介 1.1 并发简史 促使进程出现的因素:资源利用率、公平性以及便利性等。这些因素同样也促使着线程的出现。线程允许同一个进程中同时存在多个程序控制流。线程会共享进程范围内的资源,例如内存...
  • yqferin
  • yqferin
  • 2015年05月17日 09:14
  • 750

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

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

《Thinking in Java》读书笔记之并发(二)

基本的线程机制 一个线程就是在进程中一个单一的顺序控制流,因此,单个进程可以拥有多个并发执行任务 Thread类 Thread构造器只需要一个Runable对象,调用Thread对象的start(...
  • wangnan9279
  • wangnan9279
  • 2015年04月08日 15:52
  • 407

[Java Concurrency in Practice]第十四章 构建自定义的同步工具

构建自定义的同步工具类库中包含了许多存在状态依赖性的类,例如FutureTask、Semaphore和BlockingQueue等。在这些类的一些操作中有着基于状态的前提条件。例如,不能从一个空的队列...
  • qilixiang012
  • qilixiang012
  • 2015年09月09日 23:44
  • 504

[Java Concurrency in Practice]第十五章 原子变量与非阻塞同步机制

原子变量与非阻塞同步机制Java.util.concurrent包中的许多类,如Semaphore 和 ConcurrentLinkedQueue,都提供了比使用synchronized更好的性能和可...
  • qilixiang012
  • qilixiang012
  • 2015年09月11日 14:46
  • 799

[Java Concurrency in Practice]第九章 图形用户界面应用程序

图形用户界面应用程序为了维持安全性,一些特定的任务必须运行在Swing的事件线程中。然而,在事件线程中不应该执行时间较长的操作,以免用户界面失去响应。而且,由于Swing的数据结构不是线程安全的,因此...
  • qilixiang012
  • qilixiang012
  • 2015年09月01日 23:31
  • 710

[Java Concurrency in Practice]第十一章 性能与可伸缩性

性能与可伸缩性线程的最主要目的是提高程序的运行性能。线程可以使程序更加充分地发挥系统的可用处理能力,从而提高系统的资源利用率。此外,线程还可以使程序在运行现有任务的情况下立即开始处理新的任务,从而提高...
  • qilixiang012
  • qilixiang012
  • 2015年09月05日 23:48
  • 800

Java Concurrency in Practice中对象锁重入问题的理解

原因:Java Concurrency in Practice 中文版21页讲解了关于对象锁的重入的问题,一直没有读懂作者给的例子,今天琢磨了好久,找到了一个可以说服自己的理由……...
  • niexianglin_csdn
  • niexianglin_csdn
  • 2015年08月07日 20:07
  • 472

Java之GUI编程(一)

GUI全称Graphical User Interfaces,意为图形用户户界面,又称为图形用户接口,GUI指的就是采用图形方式显示的计算机操作用户界面,打个比方吧,我们点击QQ图标,就会弹出一个QQ...
  • dandanzmc
  • dandanzmc
  • 2014年04月25日 11:46
  • 34996

并发与并行(concurrency and parallelism)的思考理解

附上一个基本概念: 并发(Concurrent)与并行(Parallel)的区别。两本书里的解释:1. 《疯狂java讲义》: 并发:在同一时刻只能有一条指令执行,但多个进程指令被快速轮换执行,使得...
  • V_code
  • V_code
  • 2017年01月11日 18:56
  • 323
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:《Java Concurrency in Practice》ch9 GUI Applications
举报原因:
原因补充:

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