最近在做一个爬虫项目,自然用到了Thread技术。今天就和大家分享一下,利用Thread处理一个长任务,看看如何让等待不再漫长,让CPU不再闲置。以下代码仅供演示,用sleep(sleepTime)模拟了长任务花费的时间。读者可以通过修改threadCount改变线程数来观察单个线程和多个线程的区别以及处理时间上的差别。希望通过本文的代码演示,能够给读者留下对Thread的初步印象。
相关知识:synchronized 参见http://baike.baidu.com/view/1207212.htm
Executors.newCachedThreadPool() :
public static ExecutorService newCachedThreadPool()创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。注意,可以使用 ThreadPoolExecutor 构造方法创建具有类似属性但细节不同(例如超时参数)的线程池。
代码:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class SwingTest extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private JButton startButton = new JButton("Start");
private JButton endButton = new JButton("End");
private JProgressBar progressBar = new JProgressBar();
private JTextField textField = new JTextField(10);
private boolean flag = false;
private Integer count = 0;
public SwingTest() {
setLayout(new FlowLayout());
add(startButton);
add(endButton);
add(textField);
add(progressBar);
textField.setEditable(false);
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (flag == false) {
flag = true;
for (int threadCount = 0; threadCount < 10; threadCount++) {//修改i,改变处理任务的线程数量
ExecutorService exec = Executors.newCachedThreadPool();//管理Thread对象
exec.execute(new GoThread());
}
}
}
});
endButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
flag = false;
}
});
}
private class GoThread extends Thread implements Runnable {
public void run() {
while (count < 100 && flag == true) {
try {
sleep(200);// 模拟长任务
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (count) {
count++;
/*
* 删除if代码块,查看运行结果,你会发现进度条超过100%。
* 原因:当count进入循环时的确<100,但由于其他线程共享count,所以count值被修改。
*/
if (count > 100) {
break;
}
System.out.println(toString() + "\ncount :" + count);// 打印正在运行此代码块的线程
SwingUtilities.invokeLater(new Runnable() {
public void run() {
progressBar.setValue(count);
textField.setText("Completed : " + count + "%");
}
});
}
}
}
}
public static void main(String[] args) {
SwingTest swingTest = new SwingTest();
swingTest.setSize(200, 300);
swingTest.setTitle("SwingTest");
swingTest.setVisible(true);
}
}