• 实验五:Java多线程程序设计


    一、线程接力

    编写一个应用程序,除了主线程外,还有三个线程:first、second和third。first负责模拟一个红色的按钮从坐标(10,60)运动到(100,60);second负责模拟一个绿色的按钮从坐标(100,60)运动到(200,60)。third线程负责模拟一个蓝色的按钮从坐标(200,60)运动到(300,60)。

    阅读并分析以下程序,将程序中的代码补充完整,编译并运行程序,查看结果。

    1. package Demo01;
    2. import java.awt.*;
    3. import java.awt.event.*;
    4. public class MoveButton extends Frame implements Runnable, ActionListener {
    5. // 用Thread类声明first,second,third三个线程对象
    6. Thread first, second, third;
    7. Button redButton, greenButton, blueButton, startButton;
    8. int distance = 10;
    9. MoveButton() {
    10. // 分别创建first,second,third三个线程,用当前窗口做为该线程的目标对象
    11. first = new Thread(this);
    12. second = new Thread(this);
    13. third = new Thread(this);
    14. redButton = new Button();
    15. greenButton = new Button();
    16. blueButton = new Button();
    17. redButton.setBackground(Color.red);
    18. greenButton.setBackground(Color.green);
    19. blueButton.setBackground(Color.blue);
    20. startButton = new Button("start");
    21. startButton.addActionListener(this);
    22. setLayout(null);
    23. add(redButton);
    24. redButton.setBounds(10, 60, 15, 15);
    25. add(greenButton);
    26. greenButton.setBounds(100, 60, 15, 15);
    27. add(blueButton);
    28. blueButton.setBounds(200, 60, 15, 15);
    29. add(startButton);
    30. startButton.setBounds(200, 100, 30, 30);
    31. setTitle("线程接力");
    32. setBounds(0, 0, 10, 200);
    33. setVisible(true);
    34. validate();
    35. addWindowListener(new WindowAdapter() {
    36. public void windowClosing(WindowEvent e) {
    37. System.exit(0);
    38. }
    39. });
    40. }
    41. public void actionPerformed(ActionEvent e) {
    42. try {
    43. // 分别启动三个线程
    44. first.start();
    45. second.start();
    46. third.start();
    47. } catch (Exception exp) {
    48. }
    49. }
    50. public void run() {
    51. while (true) {
    52. // 判断当前占有CPU资源的线程是否是first
    53. if (Thread.currentThread() == first) {
    54. moveComponent(redButton);
    55. try {
    56. Thread.sleep(20);
    57. } catch (Exception exp) {
    58. }
    59. }
    60. // 判断当前占有CPU资源的线程是否是second
    61. if (Thread.currentThread() == second) {
    62. moveComponent(greenButton);
    63. try {
    64. Thread.sleep(10);
    65. } catch (Exception exp) {
    66. }
    67. }
    68. // 判断当前占有CPU资源的线程是否是third
    69. if (Thread.currentThread() == third) {
    70. moveComponent(blueButton);
    71. try {
    72. Thread.sleep(20);
    73. } catch (Exception e) {
    74. }
    75. }
    76. }
    77. }
    78. public synchronized void moveComponent(Component b) {
    79. if (Thread.currentThread() == first) {
    80. while (distance > 100 && distance <= 300)
    81. try {
    82. wait();
    83. } catch (Exception exp) {
    84. }
    85. distance = distance + 1;
    86. b.setLocation(distance, 60);
    87. if (distance >= 100) {
    88. b.setLocation(10, 60);
    89. notifyAll();
    90. }
    91. }
    92. if (Thread.currentThread() == second) {
    93. while ((distance >= 10 && distance < 100) || (distance >200 && distance <= 300))
    94. try {
    95. wait();
    96. } catch (Exception exp) {
    97. }
    98. distance = distance + 1;
    99. b.setLocation(distance, 60);
    100. if (distance > 200) {
    101. b.setLocation(100, 60);
    102. notifyAll();
    103. }
    104. }
    105. if (Thread.currentThread() == third) {
    106. while (distance >= 10 && distance < 200)
    107. try {
    108. wait();
    109. } catch (Exception exp) {
    110. }
    111. distance = distance + 1;
    112. b.setLocation(distance, 60);
    113. if (distance > 300) {
    114. distance = 10;
    115. b.setLocation(200, 60);
    116. notifyAll();
    117. }
    118. }
    119. }
    120. public static void main(String[] args) {
    121. new MoveButton().setLocationRelativeTo(null);
    122. }
    123. }

    二、线程的控制

    编写一个程序,动画显示文本域中的字符串。在窗体的南面添加三个按钮,为程序添加线程控制功能,要求点击开始按钮(startBtn),线程开始启动,文字逐个显示,并且将按钮状态改变为禁用(因为线程不能重复启动);点击暂停按钮(pauseBtn),线程暂停,文字显示停止;点击恢复按钮(resumeBtn),线程恢复运行,文字继续显示。当线程执行完毕后,恢复开始按钮的状态为可用。程序运行界面如下图所示:

     

    1. package Demo01;
    2. import java.awt.*;
    3. import java.awt.event.ActionEvent;
    4. import java.awt.event.ActionListener;
    5. import javax.swing.*;
    6. import javax.swing.border.BevelBorder;
    7. public class RunnableDemo extends JFrame implements Runnable, ActionListener {
    8. private JTextArea textArea; // 文本域组件
    9. JLabel label;
    10. Button startBtn, pauseBtn, resumeBtn;
    11. Panel panel;
    12. Thread thread;
    13. boolean move = false;
    14. // 动画显示的文本字符串
    15. private String introduction = "现在大家已经对计算机很熟悉了,如今计算机的操作"
    16. + "系统可以同时执行多个任务,在听歌的同时能够打字、下载文件,在聊天窗口打"
    17. + "字的时候,对方同时还能通过视频看到你;听到你。这一切都是使用多任务实现"
    18. + "的,Java语言使用多线程实现一个程序中的多个任务同时运行。程序员可以在程"
    19. + "序中执行多个线程,每一个线程完成一个功能,并与其他线程并发执行,这种机"
    20. + "制被称为多线程。";
    21. public static void main(String args[]) {
    22. new RunnableDemo().setLocationRelativeTo(null); // 创建本类实例对象
    23. }
    24. public RunnableDemo() {
    25. setTitle("线程的控制");
    26. label = new JLabel("多线程简介:"); // 标签组件
    27. getContentPane().add(label, BorderLayout.NORTH);// 添加标签到窗体
    28. textArea = new JTextArea("\t"); // 初始化文本域组件
    29. textArea.setBorder(new BevelBorder(BevelBorder.LOWERED));// 设置边框
    30. textArea.setLineWrap(true); // 设置自动折行
    31. getContentPane().add(textArea, BorderLayout.CENTER);// 添加文本域组件到文本框
    32. startBtn = new Button("开始");
    33. pauseBtn = new Button("暂停");
    34. resumeBtn =new Button("恢复");
    35. startBtn.addActionListener(this);
    36. pauseBtn.addActionListener(this);
    37. resumeBtn.addActionListener(this);
    38. panel = new Panel();
    39. panel.add(startBtn);
    40. panel.add(pauseBtn);
    41. panel.add(resumeBtn);
    42. getContentPane().add(panel, BorderLayout.SOUTH);
    43. setBounds(0, 0, 383, 225); // 设置窗体大小位置
    44. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    45. setVisible(true); // 显示窗体
    46. }
    47. /** Runnable接口方法,是线程的执行方法 */
    48. @Override
    49. public void run() {
    50. textArea.setText("\t");
    51. String[] intros = introduction.split(""); // 将字符串分割为数组
    52. for (String ch : intros) { // ForEach遍历字符串数组
    53. while (!move) {
    54. try {
    55. synchronized (this) {
    56. wait();
    57. }
    58. } catch (InterruptedException e) {
    59. e.printStackTrace();
    60. }
    61. }
    62. textArea.append(ch); // 添加一个字符到文本域
    63. try {
    64. Thread.sleep(100); // 线程休眠0.1秒
    65. } catch (InterruptedException e) {
    66. e.printStackTrace();
    67. }
    68. }
    69. startBtn.setEnabled(true);
    70. }
    71. @Override
    72. public void actionPerformed(ActionEvent e) {
    73. if (e.getSource() == startBtn) {
    74. thread = new Thread(this);
    75. thread.start();
    76. move = true;
    77. startBtn.setEnabled(false);
    78. } else if (e.getSource() == pauseBtn) {
    79. move = false;
    80. } else if (e.getSource() == resumeBtn) {
    81. move = true;
    82. synchronized (this) {
    83. notifyAll();
    84. }
    85. }
    86. }
    87. }

  • 相关阅读:
    基于Http Basic Authentication的接口
    不一样的VR全景购物,赋能商超和店铺购物升级
    20个CSS面试题和答案的示例
    自己动手搭建一个传奇是什么体验?下面是我搭建的详细教程,大家跟着教程做,不光是学会了技术,平时还可以帮朋友搭建
    synchronized关键字
    大华sdk使用问题
    分布式数据库中间件Mycat2
    java中分割字符串总结 - 超级无敌详细版本。不仅要熟悉各种方法还要做到灵活运用。
    HackTheBox UpDown python沙箱逃逸获得用户shell,sudo提权
    用VSC++做一个飞机大战的游戏
  • 原文地址:https://blog.csdn.net/gyh3222719788/article/details/134490807