实验1 模拟抽奖
一、实验目的
了解多线程程序的设计思路
二、实验内容
有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池用一个数组int[] arr = {10,5,20,50,100,200,500,800,2,80,300};创建两个抽奖箱(线程)设置线程名称分别为“抽奖箱1”,“抽奖箱2”,随机从arr数组中获取奖项元素并打印在控制台上
三、程序代码
public class ChouJiang {
public static void main(String[] args) {
Chou c = new Chou();
Thread t1 = new Thread(c,"抽奖箱1");//创建线程对象t1,命名为“抽奖箱1”
Thread t2 = new Thread(c,"抽奖箱2");//创建线程对象t2,命名为“抽奖箱2”
t1.start();
t2.start();
}
}
class Chou implements Runnable {
int[] arr = { 10, 5, 20, 50, 100, 200, 500, 800, 2, 80, 300 };
int num = arr.length;
boolean[] flag = new boolean[arr.length];
public void run() {
while (true) {
synchronized (this) {//设计一个同步锁
if (num > 0) {
int index = (int)(Math.random()*arr.length);//产生数组的随机索引值
int get = arr[index];
// 代表这张抽奖券抽过了
if (flag[index] != true) {
flag[index] = true;
System.out.println(Thread.currentThread().getName()
+ " 又产生了一个" + get + "元大奖");
num--;
}
}
}
}
}
}
四、实验指导
1、两个抽奖箱线程实现从抽奖池数组中抽取幸运数字
2、了解flag数组的含义,与抽奖池数组一一对应,判断该奖项是否抽出。
实验2 模拟订票
一、实验目的
掌握多线程程序的编写和线程同步的解决
二、实验内容
某电影院目前正在上映贺岁大片,共有100张票,而它有3个售票窗口售票,请设计一个程序模拟该电影院售票。
两种方式实现
继承Thread类
实现Runnable接口
三、程序代码
public class BuyTicket {
public static void main(String[] args) {//主函数
SaleWindowThread w1 = new SaleWindowThread();
Thread t1 = new Thread(w1, "第一个售票窗口");//模拟三个售票窗口
Thread t2 = new Thread(w1, "第二个售票窗口");
Thread t3 = new Thread(w1, "第三个售票窗口");
t1.start(); //启动第一个售票窗口,开始售票
t2.start(); //启动第二个售票窗口,开始售票
t3.start(); //启动第三个售票窗口,开始售票
}
}
class SaleWindowThread implements Runnable { //实现Runnable接口
private static int total_count = 100; //电影票总数
@Override
public void run() { //重写run()方法
while (true) {
if (total_count > 0) {
synchronized(this){
if (total_count > 0){
System.out.println(Thread.currentThread().getName() + "售出第" + (100 - total_count + 1) + "张票。还剩"+ (total_count - 1) + "张");
//记录售出票和剩余票数
total_count--;
}
}
}
else {
break;
}
}
}
}
四、实验指导
1、如果每次卖票延迟100毫秒,观察卖票信息是否正确
2、利用synchronized方法或代码块将共享资源封装,解决线程安全问题
实验3、打字练习
一、实验目的
掌握多线程和Timer类的使用
二、实验内容
通过GUI界面完成打字练习的功能
三、程序代码
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class Writer {
public static void main(String args[]) {
WindowTyped win=new WindowTyped();
win.setTitle("打字练习");
win.setSleepTime(3000);
}
}
class WindowTyped extends JFrame implements ActionListener,Runnable {
JTextField inputLetter;
Thread giveLetter; //负责给出字母
JLabel showLetter,showScore;
int sleepTime,score;
Color c;
WindowTyped() {
setLayout(new FlowLayout());
giveLetter=new Thread(this);
inputLetter=new JTextField(6);
showLetter =new JLabel(" ",JLabel.CENTER);
showScore = new JLabel("分数:");
showLetter.setFont(new Font("Arial",Font.BOLD,22));
add(new JLabel("显示字母:"));
add(showLetter);
add(new JLabel("输入所显示的字母(回车)"));
add(inputLetter);
add(showScore);
inputLetter.addActionListener(this);
setBounds(100,100,400,280);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
giveLetter.start(); //在AWT-Windows线程中启动giveLetter线程
}
public void run() {
char c ='a';
while(true) {
showLetter.setText(""+c+" ");
validate();
c = (char)(c+1);
if(c>'z') c = 'a';
try{ Thread.sleep(sleepTime);
}
catch(InterruptedException e){}
}
}
public void setSleepTime(int n){
sleepTime = n;
}
public void actionPerformed(ActionEvent e) {
String s = showLetter.getText().trim();
String letter = inputLetter.getText().trim();
if(s.equals(letter)) {
score++;
showScore.setText("得分"+score);
inputLetter.setText(null);
validate();
giveLetter.interrupt(); //吵醒休眠的线程,以便加快出字母的速度
}
}
}
四、实验指导
1、能够随机生成字符信息,对用户的操作有时间限制
2、有统计分数功能
实验4 月亮围绕地球
一、实验目的
学习使用Timer类创建线程
二、实验内容
编写一个应用程序,模拟月亮围绕地球
三、程序代码
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.Timer;
public class MainClass {
public static void main(String args[]) {
Sky sky= new Sky();
JFrame frame = new JFrame();
frame.add(sky);
frame.setSize(500,500);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(java.awt.Color.white);
}}
class Earth extends JLabel implements ActionListener {
JLabel moon; //显示月亮之外观
Timer timer;
double pointX[]=new double[360],
pointY[]=new double[360];
int w=200,h=200,i=0;
Earth() {
setLayout(new FlowLayout());
setPreferredSize(new Dimension(w,h));
timer=new Timer(20,this);//创建timer,振铃间隔是20毫秒当前Earth对象为其监视器
setIcon(new ImageIcon("E:\\Java程序设计\\实验报告集合\\实验九\\earth.jpg"));
setHorizontalAlignment(SwingConstants.CENTER);
moon=new JLabel(new ImageIcon("E:\\Java程序设计\\实验报告集合\\实验九\\moon.jpg"),SwingConstants.CENTER);
add(moon);
moon.setPreferredSize(new Dimension(60,60));
pointX[0]=0;
pointY[0]=h/2;
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]=0.8*pointX[i]+w/2; //坐标缩放、平移
pointY[i]=0.8*pointY[i]+h/2;
}
timer.start();
}
public void actionPerformed(ActionEvent e) {
i=(i+1)%360;
moon.setLocation((int)pointX[i]-30,(int)pointY[i]-30);
}
}
class Sky extends JLabel implements ActionListener {
Earth earth;
Timer timer;
double pointX[]=new double[360],
pointY[]=new double[360];
int w=400,h=400,i=0;
Sky() {
setLayout(new FlowLayout());
timer= new Timer(100,this);//创建timer,振铃间隔是100毫秒当前Sky对象为其监视器
setPreferredSize(new Dimension(w,h));
earth = new Earth();
add(earth);
earth.setPreferredSize(new Dimension(200,200));
pointX[0]=0;
pointY[0]=h/2;
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]=0.5*pointX[i]+w/2; //坐标缩放、平移
pointY[i]=0.5*pointY[i]+h/2;
}
timer.start();
}
public void actionPerformed(ActionEvent e) {
i=(i+1)%360;
earth.setLocation((int)pointX[i]-100,(int)pointY[i]-100);
}
}
地球图: 月亮图:
四、实验指导
如果一个圆的圆心是(0,0),那么对于给定的圆上的一点(x,y),该店按顺时针旋转a弧度后的坐标(m,n)有下列公式计算:
m=x*cos(a)-y*sin(a);
n=y*cos(a)+x*sin(a)。