JAVA上机实验7
实验名称:
多线程应用
实验目的:理解线程的概念,线程的生命周期;会使用Thread的子类创建线程;掌握Java多线程编程方法;掌握线程的控制过程以及线程资源的同步处理方法。
实验内容:
•
1、利用多线程技术模拟出龟兔赛跑的场面,设计一个线程类模拟参与赛跑的角色,创建该类的两个对象分别代表乌龟和兔子,让兔子跑快些,但在路上睡眠休息时间长些,到终点时线程运行结束。
•
•
2、编写一个Java应用程序,在主线程中在创建一个Frame类型的窗口,在该窗口中再创建1个线程giveWord。线程giveWord每隔2秒钟给出一个汉字,用户使用一种汉字输入法将该汉字输入到文本框中。
程序模版
请按照模版要求,将【代码】替换为程序代码。
WordThread.java
import java.awt.*;
public class WordThread extends Thread
{
char word;
int k=19968;
Label com;
WordThread(Label com)
{
this.com=com;
}
public void run()
{
k=19968;
while(true)
{
word=(char)k;
com.setText(""+word);
try{ 【代码1】//调用sleep方法使得线程中断6000豪秒
}
catch(InterruptedException e){}
k++;
if(k>=29968) k=19968;
}
}
}
ThreadFrame.java
import java.awt.*;
import java.awt.event.*;
public class ThreadFrame extends Frame implements
ActionListener
{
Label
wordLabel;
Button button;
TextField inputText,scoreText;
【代码2】//用WordThread声明一个giveWord对象
int
score=0;
ThreadFrame()
{
wordLabel=new Label(" ",Label.CENTER);
wordLabel.setFont(new Font("",Font.BOLD,72));
button=new Button("开始");
inputText=new TextField(3);
scoreText=new TextField(5);
scoreText.setEditable(false);
【代码3】//创建giveWord,将wordLabel传递给WordThread构造方法的参数
button.addActionListener(this);
inputText.addActionListener(this);
add(button,BorderLayout.NORTH);
add(wordLabel,BorderLayout.CENTER);
Panel southP=new Panel();
southP.add(new Label("输入标签所显示的汉字后回车:"));
southP.add(inputText);
southP.add(scoreText);
add(southP,BorderLayout.SOUTH);
setBounds(100,100,350,180);
setVisible(true);
validate();
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{ System.exit(0);
}
}
);
}
public void
actionPerformed(ActionEvent e)
{
if(e.getSource()==button)
{
if(!(【代码4】))
//giveWord调用方法isAlive()
{
giveWord=new WordThread(wordLabel);
}
try
{
【代码5】//giveWord调用方法start()
}
catch(Exception exe){}
}
else if(e.getSource()==inputText)
{
if(inputText.getText().equals(wordLabel.getText()))
{
score++;
}
scoreText.setText("得分:"+score);
inputText.setText(null);
}
}
}
WordThread.java
public class ThreadWordMainClass
{ public static void
main(String args[])
{ new
ThreadFrame();
}
3、编写一个应用程序,模拟月亮围绕地球旋转、地球围绕太阳旋转。
程序模版
请按照模版要求,将【代码】替换为程序代码。
Mycanvas.java
import java.awt.*;
public class Mycanvas extends Canvas
{ int r;
Color c;
public void setColor(Color c)
{
this.c=c;
}
public void setR(int r)
{
this.r=r;
}
public void paint(Graphics g)
{
g.setColor(c);
g.fillOval(0,0,2*r,2*r);
}
public int getR()
{ return
r;
}
}
Planet.java
import java.awt.*;
public class Planet extends Panel implements
Runnable
{ 【代码1】
//用Thread类声明一个moon对象
Mycanvas yellowBall;
double pointX[]=new double[360],
pointY[]=new double[360]; //用来表示画布左上角端点坐标的数组
int
w=100,h=100;
int
radius=30;
Planet()
{
setSize(w,h);
setLayout(null);
yellowBall=new Mycanvas();
yellowBall.setColor(Color.yellow);
add(yellowBall);
yellowBall.setSize(12,12);
yellowBall.setR(12/2);
pointX[0]=0;
pointY[0]=-radius;
double angle=1*Math.PI/180;
//刻度为1度
for(int i=0;i<359;i++)
//计算出数组中各个元素的值
{
pointX[i+1]=pointX[i]*Math.cos(angle)-Math.sin(angle)*pointY[i];
pointY[i+1]=pointY[i]*Math.cos(angle)+pointX[i]*Math.sin(angle);
}
for(int i=0;i<360;i++)
{ pointX[i]=pointX[i]+w/2;
//坐标平移
pointY[i]=pointY[i]+h/2;
}
yellowBall.setLocation((int)pointX[0]-yellowBall.getR(),
(int)pointY[0]-yellowBall.getR());
【代码2】 //创建 moon线程,当前面板做为该线程的目标对象
}
public void
start()
{
try{ moon
.start();
}
catch(Exception
exe){}
}
public void
paint(Graphics g)
{
g.setColor(Color.blue);
g.fillOval(w/2-9,h/2-9,18,18);
}
public void
run()
{
int i=0;
while(true)
{
i=(i+1)60;
yellowBall.setLocation((int)pointX[i]-yellowBall.getR(),
(int)pointY[i]-yellowBall.getR());
try{ 【代码3】 //
Thread类调用类方法sleep使得线程中断10豪秒
}
catch(InterruptedException e){}
}
}
}
HaveThreadFrame.java
import java.awt.*;
import java.awt.event.*;
public class HaveThreadFrame extends Frame
implements Runnable
{ 【代码4】
//用Thread类声明一个rotate对象
Planet earth;
double pointX[]=new double[360],
pointY[]=new double[360];
int
width,height;
int
radius=120;
HaveThreadFrame()
{
rotate=new Thread(this);
earth=new Planet();
setBounds(0,0,360,400);
width=getBounds().width;
height=getBounds().height;
pointX[0]=0;
pointY[0]=-radius;
double
angle=1*Math.PI/180;
for(int i=0;i<359;i++)
{
pointX[i+1]=pointX[i]*Math.cos(angle)-Math.sin(angle)*pointY[i];
pointY[i+1]=pointY[i]*Math.cos(angle)+pointX[i]*Math.sin(angle);
}
for(int i=0;i<360;i++)
{ pointX[i]=pointX[i]+width/2;
pointY[i]=pointY[i]+height/2;
}
setLayout(null);
setVisible(true);
validate();
addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent e)
{ System.exit(0);
}
}
);
add(earth);
earth.setLocation((int)pointX[0]-earth.getSize().width/2,
(int)pointY[0]-earth.getSize().height/2);
earth.start();
【代码5】
//用rotate调用start方法
}
public void
run()
{
int i=0;
while(true)
{
i=(i+1)60;
earth.setLocation((int)pointX[i]-earth.getSize().width/2,
(int)pointY[i]-earth.getSize().height/2);
try{ Thread.sleep(100);
}
catch(InterruptedException e){}
}
}
public void
paint(Graphics g)
{
g.setColor(Color.red);
g.fillOval(width/2-15,height/2-15,30,30);
}
}
HaveThreadFrame.java
public class ThreadRotateMainClass
{ public static void
main(String args[])
{ new
HaveThreadFrame();
}
}
4、编写一个应用程序,除了主线程外,还有两个线程:first和second。first负责模拟一个红色的按钮从坐标(10,60)运动到(100,60);second负责模拟一个绿色的按钮从坐标(100,60)运动到(200,60)。
程序模版
请按照模版要求,将【代码】替换为程序代码。
MoveButton.java
import java.awt.*;
import java.awt.event.*;
public class MoveButton extends Frame implements
Runnable,ActionListener
{ 【代码1】//用Thread类声明first,second两个线程对象
Button redButton,greenButton,startButton;
int
distance=10;
MoveButton()
{
【代码2】
//创建first线程,当前窗口做为该线程的目标对象
【代码3】
//创建first线程,当前窗口做为该线程的目标对象
redButton=new Button();
greenButton=new Button();
redButton.setBackground(Color.red);
greenButton.setBackground(Color.green);
startButton=new Button("start");
startButton.addActionListener(this);
setLayout(null);
add(redButton);
redButton.setBounds(10,60,15,15);
add(greenButton);
greenButton.setBounds(100,60,15,15);
add(startButton);
startButton.setBounds(10,100,30,30);
setBounds(0,0,300,200);
setVisible(true);
validate();
addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent e)
{ System.exit(0);
}
}
);
}
public void actionPerformed(ActionEvent e)
{
try{
first.start();
second.start();
}
catch(Exception exp){}
}
public void run()
{
while(true)
{
if(【代码4】)
//判断当前占有CPU资源的线程是否是first
{
moveComponent(redButton);
try{
Thread.sleep(20);
}
catch(Exception exp){}
}
if(【代码5】)
//判断当前占有CPU资源的线程是否是second
{
moveComponent(greenButton);
try{ Thread.sleep(10);
}
catch(Exception exp){}
}
}
}
public synchronized void moveComponent(Component b)
{
if(Thread.currentThread()==first)
{
while(distance>100&&distance<=200)
try{ wait();
}
catch(Exception
exp){}
distance=distance+1;
b.setLocation(distance,60);
if(distance>=100)
{
b.setLocation(10,60);
notifyAll();
}
}
if(Thread.currentThread()==second)
{
while(distance>=10&&distance<100)
try{ wait();
}
catch(Exception exp){}
distance=distance+1;
b.setLocation(distance,60);
if(distance>200)
{
distance=10;
b.setLocation(100,60);
notifyAll();
}
}
}
}
MoveButtonMainClass.java
public class MoveButtonMainClass
{ public static void
main(String args[])
{ new
MoveButton();
}
加载中,请稍候......