High memory usage with ExecutorService.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileFilter;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import javax.imageio.ImageIO;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingWorker;
import org.imgscalr.Scalr;

public class ImageThumbList extends JFrame {
	private final int THUMB_WIDTH;
	private final int THUMB_HEIGHT;
	private final int HORIZONTAL_SPACING;
	private final int VERTICAL_SPACING;
	private final Color BACKGROUND;
	private final String IMAGES_DIR_PATH;
	private final double THUMB_RATIO;
	private LinkedBlockingQueue<File> queue;
	private boolean useSwingWorker;
	private JList iconJList;
	private JScrollPane iconJListScrollPane;
	private DefaultListCellRenderer iconJListRenderer;
	private DefaultListModel iconJListModel;

	public ImageThumbList() {
		THUMB_WIDTH = 174;
		THUMB_HEIGHT = 174;
		HORIZONTAL_SPACING = 10;
		VERTICAL_SPACING = 10;
		IMAGES_DIR_PATH = ImagePath;
		THUMB_RATIO = (double) THUMB_WIDTH / (double) THUMB_HEIGHT;
		BACKGROUND = new Color(Integer.parseInt("646464", 16));
		useSwingWorker = true;
		initComponents();
	}

	private void initComponents() {
		setLayout(new BorderLayout());
		iconJListModel = new DefaultListModel();
		iconJList = new JList(iconJListModel);
		iconJListRenderer = (DefaultListCellRenderer) iconJList
				.getCellRenderer();
		iconJListScrollPane = new JScrollPane(iconJList);
		iconJList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
		iconJList.setFixedCellHeight(THUMB_HEIGHT + VERTICAL_SPACING);
		iconJList.setFixedCellWidth(THUMB_WIDTH + HORIZONTAL_SPACING);
		iconJList.setBackground(BACKGROUND);
		iconJList.setVisibleRowCount(-1);
		iconJListRenderer.setHorizontalAlignment(JLabel.CENTER);
		iconJListRenderer.setVerticalAlignment(JLabel.CENTER);
		iconJListScrollPane
				.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		add(iconJListScrollPane, BorderLayout.CENTER);
	}

	public void start() {
		queue = new LinkedBlockingQueue<File>();
		queue.addAll(Arrays.asList(new File(IMAGES_DIR_PATH)
				.listFiles(new FileFilter() {
					@Override
					public boolean accept(File dir) {
						return dir.isFile();
					}
				})));

		if (useSwingWorker) {
			new SimpleThumbnailGenerator().execute();
		} else {
			new Thread(new ExecutorServiceThumbnailGenerator()).start();
		}
	}

	private class SimpleThumbnailGenerator extends
			SwingWorker<Void, BufferedImage> {
		@Override
		public Void doInBackground() {
			while (!isCancelled()) {
				File file = null;
				try {
					file = queue.take();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				publish(getThumbnail(file));
			}
			return null;
		}

		@Override
		public void process(List<BufferedImage> lista) {
			for (BufferedImage c : lista) {
				if (c != null) {
					iconJListModel.addElement(new ImageIcon(c));
				}
			}
		}
	}

	private class ExecutorServiceThumbnailGenerator implements Runnable {
		private ExecutorService pool;

		public ExecutorServiceThumbnailGenerator() {
			pool = Executors.newFixedThreadPool(Runtime.getRuntime()
					.availableProcessors());
		}

		@Override
		public void run() {
			try {
				while (true) {
					pool.execute(new ThumbnailGenerator(queue.take()));
				}
			} catch (InterruptedException ie) {
				ie.printStackTrace();
			} finally {
				pool.shutdown();
			}
		}
	}

	private class ThumbnailGenerator extends SwingWorker<Void, BufferedImage> {
		File file;

		ThumbnailGenerator(File file) {
			this.file = file;
		}

		@Override
		public Void doInBackground() {
			publish(getThumbnail(file));
			return null;
		}

		@Override
		public void process(List<BufferedImage> lista) {
			for (BufferedImage c : lista) {
				if (c != null) {
					iconJListModel.addElement(new ImageIcon(c));
				}
			}
		}
	}

	private BufferedImage getThumbnail(File file) {
		BufferedImage thumbnail = null;
		if (file != null) {
			try {
				thumbnail = ImageIO.read(file);
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (thumbnail != null) {
				int thumbWidth = THUMB_WIDTH;
				int thumbHeight = THUMB_HEIGHT;
				// determine thumbnail size from WIDTH and HEIGHT
				double imageRatio = (double) thumbnail.getWidth(null)
						/ (double) thumbnail.getHeight(null);
				if (THUMB_RATIO < imageRatio) {
					thumbHeight = (int) (thumbWidth / imageRatio);
				} else {
					thumbWidth = (int) (thumbHeight * imageRatio);
				}
				thumbnail = Scalr.resize(thumbnail, thumbWidth, thumbHeight);
			}
		}
		return thumbnail;
	}

	public static void main(String[] args) {
		java.awt.EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				ImageThumbList frame = new ImageThumbList();
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				frame.setSize(800, 445);
				frame.setPreferredSize(new Dimension(800, 445));
				frame.setLocationRelativeTo(null);
				frame.setVisible(true);
				frame.start();
			}
		});
	}
}
相關文章
相關標籤/搜索