上机实验9 多线程案例

简介: 上机实验9 多线程案例

实验1 模拟抽奖

一、实验目的

了解多线程程序的设计思路

二、实验内容

有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池用一个数组int[] arr = {10,5,20,50,100,200,500,800,2,80,300};创建两个抽奖箱(线程)设置线程名称分别为抽奖箱1”抽奖箱2”,随机从arr数组中获取奖项元素并打印在控制台上

三、程序代码

1. public class ChouJiang {
2.  public static void main(String[] args) {
3.    Chou c = new Chou();
4.    Thread t1 = new Thread(c,"抽奖箱1");//创建线程对象t1,命名为“抽奖箱1”
5.    Thread t2 = new Thread(c,"抽奖箱2");//创建线程对象t2,命名为“抽奖箱2”
6.       t1.start();
7.       t2.start();
8.       }
9. }
10. class Chou implements Runnable {
11.     int[] arr = { 10, 5, 20, 50, 100, 200, 500, 800, 2, 80, 300 };
12.     int num = arr.length;
13. boolean[] flag = new boolean[arr.length];
14.     public void run() {
15.         while (true) {
16. synchronized (this) {//设计一个同步锁
17. if (num > 0) {
18.                     int index = (int)(Math.random()*arr.length);//产生数组的随机索引值
19.                     int get = arr[index];
20. // 代表这张抽奖券抽过了
21. if (flag[index] != true) {
22.                         flag[index] = true;
23.                         System.out.println(Thread.currentThread().getName()
24. + " 又产生了一个" + get + "元大奖");
25.                         num--;
26.                     }
27.                 }
28.             }
29.         }
30.     }
31. }

四、实验指导

1、两个抽奖箱线程实现从抽奖池数组中抽取幸运数字

2、了解flag数组的含义,与抽奖池数组一一对应,判断该奖项是否抽出。

实验2 模拟订票

一、实验目的

掌握多线程程序的编写和线程同步的解决

二、实验内容

   某电影院目前正在上映贺岁大片,共有100张票,而它有3个售票窗口售票,请设计一个程序模拟该电影院售票。

两种方式实现

继承Thread类

实现Runnable接口

三、程序代码

1. public class BuyTicket {
2.  public static void main(String[] args) {//主函数
3.    SaleWindowThread w1 = new SaleWindowThread();
4.    Thread t1 = new Thread(w1, "第一个售票窗口");//模拟三个售票窗口
5.    Thread t2 = new Thread(w1, "第二个售票窗口");
6.    Thread t3 = new Thread(w1, "第三个售票窗口");
7.    t1.start();   //启动第一个售票窗口,开始售票
8.    t2.start();   //启动第二个售票窗口,开始售票
9.    t3.start();   //启动第三个售票窗口,开始售票
10.   }
11. }
12. class SaleWindowThread implements Runnable {  //实现Runnable接口
13.   private static int total_count = 100;   //电影票总数
14.   @Override
15.   public void run() { //重写run()方法
16.     while (true) {
17.       if (total_count > 0) {
18.         synchronized(this){
19.           if (total_count > 0){
20.             System.out.println(Thread.currentThread().getName() + "售出第" + (100 - total_count + 1) + "张票。还剩"+ (total_count - 1) + "张");  
21.             //记录售出票和剩余票数
22.         total_count--;
23.           }
24.         }
25.       } 
26.       else {
27.         break;
28.       }
29.     }
30.   }
31. }

四、实验指导

1、如果每次卖票延迟100毫秒,观察卖票信息是否正确

2、利用synchronized方法或代码块将共享资源封装,解决线程安全问题

实验3、打字练习

一、实验目的

掌握多线程和Timer类的使用

二、实验内容

通过GUI界面完成打字练习的功能

三、程序代码

1. import java.awt.Color;
2. import java.awt.FlowLayout;
3. import java.awt.Font;
4. import java.awt.event.ActionEvent;
5. import java.awt.event.ActionListener;
6. 
7. import javax.swing.JFrame;
8. import javax.swing.JLabel;
9. import javax.swing.JTextField;
10. 
11. public class Writer {
12.      public static void main(String args[]) {
13.           WindowTyped win=new WindowTyped();
14.           win.setTitle("打字练习");
15.           win.setSleepTime(3000);
16.        }
17. }
18. class WindowTyped extends JFrame implements ActionListener,Runnable {
19.      JTextField inputLetter;
20.      Thread giveLetter;       //负责给出字母
21.      JLabel showLetter,showScore;
22.      int sleepTime,score;
23.      Color c;
24.      WindowTyped() {
25.         setLayout(new FlowLayout());
26.         giveLetter=new Thread(this);
27.         inputLetter=new JTextField(6);
28.         showLetter =new JLabel(" ",JLabel.CENTER);
29.         showScore  = new JLabel("分数:");
30.         showLetter.setFont(new Font("Arial",Font.BOLD,22));
31.         add(new JLabel("显示字母:"));
32.         add(showLetter);
33.         add(new JLabel("输入所显示的字母(回车)"));
34.         add(inputLetter);
35.         add(showScore);
36.         inputLetter.addActionListener(this);
37.         setBounds(100,100,400,280);
38.         setVisible(true);
39.         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
40.         giveLetter.start();    //在AWT-Windows线程中启动giveLetter线程
41.      }
42.      public void run() {
43.         char c ='a';
44.         while(true) {
45.            showLetter.setText(""+c+" ");
46.            validate();
47.            c = (char)(c+1);
48.            if(c>'z') c = 'a';
49.            try{ Thread.sleep(sleepTime);
50.            }
51.            catch(InterruptedException e){}
52.         }
53.      }
54.      public void setSleepTime(int n){
55.         sleepTime = n;
56.      }
57.      public void actionPerformed(ActionEvent e) {
58.         String s = showLetter.getText().trim();
59.         String letter = inputLetter.getText().trim();
60.         if(s.equals(letter)) {
61.            score++;
62.            showScore.setText("得分"+score);
63.            inputLetter.setText(null);
64.            validate();
65.            giveLetter.interrupt();  //吵醒休眠的线程,以便加快出字母的速度
66.         }
67.      }
68.   }

四、实验指导

1、能够随机生成字符信息,对用户的操作有时间限制

2、有统计分数功能

实验4 月亮围绕地球

一、实验目的

学习使用Timer类创建线程

二、实验内容

编写一个应用程序,模拟月亮围绕地球

三、程序代码

1. import java.awt.Dimension;
2. import java.awt.FlowLayout;
3. import java.awt.event.ActionEvent;
4. import java.awt.event.ActionListener;
5. 
6. import javax.swing.ImageIcon;
7. import javax.swing.JFrame;
8. import javax.swing.JLabel;
9. import javax.swing.SwingConstants;
10. import javax.swing.Timer;
11. 
12. public class MainClass {
13.     public static void main(String args[]) {
14.     Sky sky= new Sky();
15.     JFrame frame = new JFrame();
16.     frame.add(sky);
17.     frame.setSize(500,500);
18.     frame.setVisible(true);
19.     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
20.     frame.getContentPane().setBackground(java.awt.Color.white);
21.   }}
22. class Earth extends JLabel implements ActionListener {
23.          JLabel moon;  //显示月亮之外观 
24.          Timer timer;
25.          double pointX[]=new double[360], 
26.                 pointY[]=new double[360]; 
27.          int w=200,h=200,i=0;
28.          Earth() {
29.            setLayout(new FlowLayout());
30.            setPreferredSize(new Dimension(w,h));
31.            timer=new Timer(20,this);//创建timer,振铃间隔是20毫秒当前Earth对象为其监视器     
32.            setIcon(new ImageIcon("E:\\Java程序设计\\实验报告集合\\实验九\\earth.jpg"));
33.            setHorizontalAlignment(SwingConstants.CENTER);
34.            moon=new JLabel(new ImageIcon("E:\\Java程序设计\\实验报告集合\\实验九\\moon.jpg"),SwingConstants.CENTER);
35.        add(moon);
36.            moon.setPreferredSize(new Dimension(60,60));
37.            pointX[0]=0;                
38.            pointY[0]=h/2;
39.            double angle=1*Math.PI/180;   //刻度为1度  
40.        for(int i=0;i<359;i++) {      //计算出数组中各个元素的值 
41.              pointX[i+1]=pointX[i]*Math.cos(angle)-Math.sin(angle)*pointY[i];
42.              pointY[i+1]=pointY[i]*Math.cos(angle)+pointX[i]*Math.sin(angle);
43.            }
44.        for(int i=0;i<360;i++) {            
45.              pointX[i]=0.8*pointX[i]+w/2;    //坐标缩放、平移     
46.              pointY[i]=0.8*pointY[i]+h/2;
47.            }
48.            timer.start();
49.          }
50.          public void actionPerformed(ActionEvent e) {
51.              i=(i+1)%360;
52.              moon.setLocation((int)pointX[i]-30,(int)pointY[i]-30);
53.          }
54.       }
55. class Sky extends JLabel implements ActionListener {
56.      Earth earth;
57.      Timer timer;
58.      double pointX[]=new double[360], 
59.             pointY[]=new double[360]; 
60.      int w=400,h=400,i=0;
61.      Sky() {
62.        setLayout(new FlowLayout());
63.        timer= new Timer(100,this);//创建timer,振铃间隔是100毫秒当前Sky对象为其监视器
64.        setPreferredSize(new Dimension(w,h));
65.        earth = new Earth();
66.        add(earth);
67.        earth.setPreferredSize(new Dimension(200,200));
68.        pointX[0]=0;                
69.        pointY[0]=h/2;
70.        double angle=1*Math.PI/180;   //刻度为1度  
71.        for(int i=0;i<359;i++) {      //计算出数组中各个元素的值 
72.          pointX[i+1]=pointX[i]*Math.cos(angle)-Math.sin(angle)*pointY[i];
73.          pointY[i+1]=pointY[i]*Math.cos(angle)+pointX[i]*Math.sin(angle);
74.        }
75.        for(int i=0;i<360;i++) {            
76.          pointX[i]=0.5*pointX[i]+w/2;    //坐标缩放、平移
77.          pointY[i]=0.5*pointY[i]+h/2;
78.        }
79.        timer.start();
80.      }
81.      public void actionPerformed(ActionEvent e) {
82.          i=(i+1)%360;
83.          earth.setLocation((int)pointX[i]-100,(int)pointY[i]-100);
84.      }
85. }

地球图:  月亮图:

四、实验指导

如果一个圆的圆心是(0,0),那么对于给定的圆上的一点(x,y),该店按顺时针旋转a弧度后的坐标(m,n)有下列公式计算:

    m=x*cos(a)-y*sin(a);

    n=y*cos(a)+x*sin(a)。

目录
相关文章
|
3月前
多线程案例-定时器(附完整代码)
多线程案例-定时器(附完整代码)
271 0
|
3月前
|
设计模式 监控 Java
Java多线程基础-11:工厂模式及代码案例之线程池(一)
本文介绍了Java并发框架中的线程池工具,特别是`java.util.concurrent`包中的`Executors`和`ThreadPoolExecutor`类。线程池通过预先创建并管理一组线程,可以提高多线程任务的效率和响应速度,减少线程创建和销毁的开销。
64 2
|
3月前
|
安全 Java
Java多线程基础-10:代码案例之定时器(一)
`Timer` 是 Java 中的一个定时器类,用于在指定延迟后执行指定的任务。它常用于实现定时任务,例如在网络通信中设置超时或定期清理数据。`Timer` 的核心方法是 `schedule()`,它可以安排任务在延迟一段时间后执行。`
74 1
|
3月前
|
Java Python 开发者
Python 学习之路 01基础入门---【Python安装,Python程序基本组成】
线程池详解与异步任务编排使用案例-xian-cheng-chi-xiang-jie-yu-yi-bu-ren-wu-bian-pai-shi-yong-an-li
496 3
Python 学习之路 01基础入门---【Python安装,Python程序基本组成】
|
3月前
|
SQL Dubbo Java
案例分析|线程池相关故障梳理&总结
本文作者梳理和分享了线程池类的故障,分别从故障视角和技术视角两个角度来分析总结,故障视角可以看到现象和教训,而技术视角可以透过现象看到本质更进一步可以看看如何避免。
84733 136
案例分析|线程池相关故障梳理&总结
|
8天前
|
消息中间件 安全 Kafka
"深入实践Kafka多线程Consumer:案例分析、实现方式、优缺点及高效数据处理策略"
【8月更文挑战第10天】Apache Kafka是一款高性能的分布式流处理平台,以高吞吐量和可扩展性著称。为提升数据处理效率,常采用多线程消费Kafka数据。本文通过电商订单系统的案例,探讨了多线程Consumer的实现方法及其利弊,并提供示例代码。案例展示了如何通过并行处理加快订单数据的处理速度,确保数据正确性和顺序性的同时最大化资源利用。多线程Consumer有两种主要模式:每线程一个实例和单实例多worker线程。前者简单易行但资源消耗较大;后者虽能解耦消息获取与处理,却增加了系统复杂度。通过合理设计,多线程Consumer能够有效支持高并发数据处理需求。
22 4
|
3月前
|
Python
Python学习之路 02 之分支结构
Python学习之路 02 之分支结构
474 0
Python学习之路 02 之分支结构
|
3月前
|
Java
线程池详解与异步任务编排使用案例-xian-cheng-chi-xiang-jie-yu-yi-bu-ren-wu-bian-pai-shi-yong-an-li
线程池详解与异步任务编排使用案例-xian-cheng-chi-xiang-jie-yu-yi-bu-ren-wu-bian-pai-shi-yong-an-li
63 0
|
3月前
|
设计模式 安全 Java
多线程(代码案例: 单例模式, 阻塞队列, 生产者消费者模型,定时器)
多线程(代码案例: 单例模式, 阻塞队列, 生产者消费者模型,定时器)
36 2
|
3月前
|
设计模式 安全 Java
Java多线程案例-Java多线程(3)
Java多线程案例-Java多线程(3)
19 1

相关实验场景

更多