注意
一、实验目的:
练习多线程类的两种实现方法,理解多线程程序的生命周期。
二、实验内容:
编写一多线程程序,实现如下功能:
(1)一个线程进行阶乘和的运算(1!+2!+3!…+30!),每次阶乘计算时间随机间隔0.5-1秒;
(2)另一个线程每隔1秒时间读取上个线程的运算结果和计算进程,并在图形界面中实时显示结果。
三、实验要求:
1、正确设计显示运行结果和计算进程的图形用户界面;
2、分别采用Thread类的子类和Runnable接口两种方式完成两个线程的设计;
3、进行全面的测试并分析测试结果;
4、简要说明你在该实验中的收获与体会。
参考代码
Calculate 类
import java.math.BigInteger;
public class Calculate extends Thread {//继承Thread类
private int n;
private Logable logable;
public Calculate(int n, Logable logable) {
this.n=n;
this.logable=logable;
}
private void caculate() throws InterruptedException {
BigInteger result=BigInteger.valueOf(1);
BigInteger sum=BigInteger.valueOf(0);
StringBuilder sb=new StringBuilder();
for(int i=1;i<=n;i++) {
try {
result=result.multiply(BigInteger.valueOf(i));
sum=sum.add(result);
sb.append((i==1?"":"+")+i+"!");
logable.log(i,sb.toString()+"="+sum);
Thread.sleep((int)(500+Math.random()*500));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void run(){
try {
caculate();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Logable 类
public interface Logable {
public void log(int step,String content);
}
ThreadUI 类
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ThreadUI {
private JTextField textField;
private JTextArea consoleArea;
private Calculate cal;
private JProgressBar progressBar=new JProgressBar();
public ThreadUI() {
JFrame frame=new JFrame("阶乘计算程序");
frame.setSize(600,400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//北侧操作栏
frame.setLayout(new BorderLayout());
JPanel northpan=new JPanel();
JLabel label=new JLabel("输入值N:");
textField=new JTextField(10);
JButton startBtn=new JButton("开始计算");
startAction(startBtn);
JButton pauseBtn=new JButton("暂停计算");
pauseAction(pauseBtn);
JButton stopBtn=new JButton("停止计算");
stopAction(stopBtn);
northpan.add(label);
northpan.add(textField);
northpan.add(startBtn);
northpan.add(pauseBtn);
northpan.add(stopBtn);
frame.add(northpan,BorderLayout.NORTH);
//记录计算过程及结果
consoleArea=new JTextArea();//组件
JScrollPane scrollPane=new JScrollPane(consoleArea);//带滚动条的容器
frame.add(scrollPane,BorderLayout.CENTER);//在添加滚动条设置的同时设置其位置
frame.add(progressBar,BorderLayout.SOUTH);//在添加滚动条的同时设置其位置
frame.setVisible(true);
}
private void startAction(JButton startBtn) {
startBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
consoleArea.setText(null);
String input=textField.getText();
int n=Integer.valueOf(input);
progressBar.setMaximum(n);//设置进度条的最大值
cal =new Calculate(n,new Logable() {//初始状态
public void log(int step,String content) {//自定义匿名内部类
consoleArea.append(content+"\n");
progressBar.setValue(step);//设置进度
progressBar.setStringPainted(true);//显示百分比
}
});
cal.start();//开始计算,调用run方法
}
});
}
private void pauseAction(JButton pauseBtn) {
pauseBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
cal.suspend();
String pauseText=pauseBtn.getText();
if(pauseText.equals("暂停计算")) {
cal.suspend();
pauseBtn.setText("继续计算");
}else {
cal.resume();
pauseBtn.setText("暂停计算");
}
}
});
}
private void stopAction(JButton stopBtn) {
stopBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
cal.stop();
}
});
}
public static void main(String[] args) {
new ThreadUI();
}
}