实验报告 Java进程与线程
【实验目的】
1. 熟练掌握Java中进行与线程的概念,编程原理,及应用领域。
2. 正确理解进程与线程的区别和应用领域。
【实验内容】
1. 编写一个计时精度为1/24秒的数字秒表程序,具有开始、暂停、继续和复位功能。
下图给出截图
程序代码:
StopWatch.java
package com;
import java.awt.BorderLayout;
import java.awt.Font;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class StopWatch extends JFrame {
JLabel contentLab = new JLabel(“00 : 00 : 00.00”); // 计时内容标签
long begin, elapsed, total; // 开始时间、当前逝去时间、总逝去时间
boolean b = false; // 是否刷新时间
/**** 初始化UI ****/
private void init() {
setLayout(new BorderLayout());
JButton startBtn = new JButton(“开始”);
JButton pauseBtn = new JButton(“暂停”);
JButton resumeBtn = new JButton(“继续”);
JButton resetBtn = new JButton(“复位”);
pauseBtn.setEnabled(false); // 设置各按钮的初始状态
resumeBtn.setEnabled(false);
resetBtn.setEnabled(false);
JPanel top = new JPanel();
top.add(startBtn);
top.add(pauseBtn);
top.add(resumeBtn);
top.add(resetBtn);
add(top, BorderLayout.NORTH);
contentLab.setFont(new Font(“Tohoma”, Font.BOLD, 40));
contentLab.setHorizontalAlignment(JLabel.CENTER);
add(contentLab, BorderLayout.CENTER);
/**** 按钮点击事件处理 ****/
startBtn.addActionListener(e -> {
b = true; // 刷新时间
total = 0; // 总逝去时间清零
begin = System.currentTimeMillis(); // 修改开始时间
startBtn.setEnabled(false); // 修改各按钮的状态
pauseBtn.setEnabled(true);
resetBtn.setEnabled(true);
});
pauseBtn.addActionListener(e -> {
b = false; // 停止刷新时间
total += elapsed; // 累加到总逝去时间
pauseBtn.setEnabled(false);
resumeBtn.setEnabled(true);
});
resumeBtn.addActionListener(e -> {
b = true;
begin = System.currentTimeMillis();
pauseBtn.setEnabled(true);
resumeBtn.setEnabled(false);
});
resetBtn.addActionListener(e -> {
b = false;
contentLab.setText(“00 : 00 : 00.00”);
startBtn.setEnabled(true);
pauseBtn.setEnabled(false);
resumeBtn.setEnabled(false);
resetBtn.setEnabled(false);
});
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400, 200);
setVisible(true);
}
public void on() {
new Thread(() -> { // 创建线程对象(参数为Lambda表达式)
while (true) { // 死循环
if (b) { // 刷新时间
elapsed = System.currentTimeMillis() – begin; // 计算当前逝去的时间
int h = (int) ((total + elapsed) / (60 * 60 * 1000)); // 计算各分量
int m = (int) ((total + elapsed) % (60 * 60 * 1000) / (60 * 1000));
int s = (int) ((total + elapsed) % (60 * 1000) / 1000);
int ms = (int) ((total + elapsed) % 1000 / (1000 / 24));
contentLab.setText(String.format(“%02d : %02d : %02d.%02d”, h, m, s, ms));
}
try {
Thread.sleep(1000 / 24); // 休眠1/24秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start(); // 启动线程
}
public static void main(String[] args) {
StopWatch t = new StopWatch();
t.init();
t.on();
}
}
程序输出结果截图:(要求对上面的界面按钮的颜色进行简单修改)。
线程综合练习:
WebSiteCounter.java
package ch11;
public class WebSiteCounter {
public static void main(String args[]) throws InterruptedException {
WebSite site = new WebSite();
new Thread(site, “用户1”).start(); // 模拟3个用户
new Thread(site, “用户2”).start();
new Thread(site, “用户3”).start();
Thread.sleep(100); // 未捕获InterruptedException(由所在方法抛出)
}
}
class WebSite implements Runnable { // 网站
int count = 0; // 访问计数器
public void run() {
synchronized (this) {
System.out.println(Thread.currentThread().getName() + “:第 ” + (++count) + ” 位访问者”);
}
}
}
任务:搜集资料,解析 synchronized (this) { 代码的功能。
同步习题
• 选择题
1.编译运行一下代码会发生什么( )。
public class Bgroudn extends Thread{
public static void main(String [] args){
Bgroud b=new Bgroud();
b.run();
}
public void start(){
for(int i=0;i<10;i++){
System.out.println(“Values of i=”+i);
}
}
}
• 编译错误,Thread类中的run方法没有定义
• 运行错误,Thread类中的run方法没有定义
• 编译无错,打印0到9
• 编译无错,不打印任何值
2、编译运行下面的代码会发生什么( )。
public class Test{
public static void main(String [] args){
Pmcraven pm1=new Pmcraven(“one”);
pm1.run();
Pmcraven pm2=new Pmcraven(“two”);
pm2.run();
}
}
class Pmcraven extends Thread{
private String sTname=””;
Pmcraven(String s){
sTname=s;
}
public void run(){
for(int i=0;i<2;i++){
try{
sleep(1000);
}catch(InterruptedException ex){
yield();
System.out.println(sTname);
}
}
}
}
• 编译错误
• 输出“One One Two Two”
• 输出“One Two One Two”
• 输出“One Two Two One”
二、简答题
1. 线程的基本概念、线程的基本状态及状态之间的关系?
答:
2.Thread类和Runnable有什么不同?
答:
3.线程和进程之间有什么区别?
答:
4.多线程有几种实现方法?都是什么?
答:
上机指导
1.子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码。
任务:编写上述题目的功能代码:类名Lab01.java
package com;
/**
* 子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,
*
*/
public class Lab01{
}