實驗五 Java多線程程式設計

来源:https://www.cnblogs.com/moeyur/archive/2023/05/09/17386429.html
-Advertisement-
Play Games

實驗五 Java多線程程式設計 實驗目的 1. 掌握Runnable介面實現多線程的方法 2. 掌握Thread類實現多線程的用法 3. 掌握Java語言中多線程編程的基本方法 ...


目的

1. 掌握Runnable介面實現多線程的方法
2. 掌握Thread類實現多線程的用法
3. 掌握Java語言中多線程編程的基本方法

1. 線程接力(45分)

要求:編寫一個應用程式,除了主線程外,還有三個線程:first、second和third。
first負責模擬一個紅色的按鈕從坐標(10,60)運動到(100,60);
second負責模擬一個綠色的按鈕從坐標(100,60)運動到(200,60);
third線程負責模擬一個藍色的按鈕從坐標(200,60)運動到(300,60)。

2. 線程的控制(45分)

要求:編寫一個程式,動畫顯示文本域中的字元串。在窗體的南面添加三個按鈕,為程式添加線程式控制制功能。

點擊開始按鈕(startBtn),線程開始啟動,文字逐個顯示,並且將按鈕狀態改變為禁用(因為線程不能重覆啟動)
點擊暫停按鈕(pauseBtn),線程暫停,文字顯示停止
點擊恢復按鈕(resumeBtn),線程恢復運行,文字繼續顯示
當線程執行完畢後,恢復開始按鈕的狀態為可用。

線程接力

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class MoveButton extends Frame implements Runnable, ActionListener {
    // 用Thread類聲明first,second,third三個線程對象
	Thread first,second,third;
    Button redButton, greenButton, blueButton, startButton;
    int distance = 10;

    MoveButton() {
        //分別創建first,second,third三個線程,用當前視窗做為該線程的目標對象
        first =new Thread(this);
        second = new Thread(this);
        third = new Thread(this);
        redButton = new Button();
        greenButton = new Button();
        blueButton = new Button();
        redButton.setBackground(Color.red);
        greenButton.setBackground(Color.green);
        blueButton.setBackground(Color.blue);
        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(blueButton);
        blueButton.setBounds(200, 60, 15, 15);
        add(startButton);
        startButton.setBounds(10, 100, 30, 30);

        JLabel label1 = new JLabel("your name   不啦不啦不啊咯");
        add(label1);
        label1.setBounds(50, 105, 150, 25);

        setTitle("線程接力");
        setBounds(0, 0, 400, 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();
            third.start();

        } catch (Exception exp) {
        }
    }

    public void run() {
        while (true) {
            // 判斷當前占有CPU資源的線程是否是first
            if (Thread.currentThread()==first) {
                moveComponent(redButton);
                try {
                    Thread.sleep(20);
                } catch (Exception exp) {
                }
            }
// 判斷當前占有CPU資源的線程是否是second
            if (Thread.currentThread()==second) {
                moveComponent(greenButton);
                try {
                    Thread.sleep(10);
                } catch (Exception exp) {
                }
            }
// 判斷當前占有CPU資源的線程是否是third
            if (Thread.currentThread()==third) {
                moveComponent(blueButton);
                try {
                    Thread.sleep(20);
                } catch (Exception e) {

                }
            }
        }
    }

    public synchronized void moveComponent(Component b) {
        if (Thread.currentThread() == first) {
            while (distance > 100 && distance <= 300)
                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) && (distance>200 && distance<300) )
                try {
                    wait();
                } catch (Exception exp) {
                }
            distance = distance + 1;
            b.setLocation(distance, 60);
            if (distance > 200) {
                b.setLocation(100, 60);
                notifyAll();
            }
        }
        if (Thread.currentThread() == third) {
            while (distance<200)
                try {
                    wait();
                } catch (Exception exp) {
                }
            distance = distance + 1;
            b.setLocation(distance, 60);
            if (distance > 300) {
                distance = 10;
                b.setLocation(200, 60);
                notifyAll();
            }
        }
    }

    public static void main(String[] args) {
        new MoveButton().setLocationRelativeTo(null);
    }
}
程式運行截圖

自己截圖粘貼進markdown

實驗總結

“線程接力”體現了Java多線程編程的線程切換特性,通過三個線程對一個組件進行移動,實現了多個線程間的協同作用。

線程的控制

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.BevelBorder;

public class RunnableDemo extends JFrame implements Runnable, ActionListener {
    private JTextArea textArea; // 文本域組件
    JLabel label;
    Button startBtn, pauseBtn, resumeBtn;
    Panel panel;
    Thread thread;
    boolean move = false;

    // 動畫顯示的文本字元串
    private String introduction = "現在大家已經對電腦很熟悉了,如今電腦的操作"
            + "系統可以同時執行多個任務,在聽歌的同時能夠打字、下載文件,在聊天視窗打"
            + "字的時候,對方同時還能通過視頻看到你;聽到你。這一切都是使用多任務實現"
            + "的,Java語言使用多線程實現一個程式中的多個任務同時運行。程式員可以在程"
            + "序中執行多個線程,每一個線程完成一個功能,並與其他線程併發執行,這種機"
            + "制被稱為多線程。";

    public static void main(String args[]) {
        new RunnableDemo().setLocationRelativeTo(null); // 創建本類實例對象
    }

    public RunnableDemo() {
        setTitle("線程的控制");
        label = new JLabel("多線程簡介: your name   不啦不啦不啊咯"); // 標簽組件
        getContentPane().add(label, BorderLayout.NORTH);// 添加標簽到窗體
        textArea = new JTextArea("\t"); // 初始化文本域組件
        textArea.setBorder(new BevelBorder(BevelBorder.LOWERED));// 設置邊框
        textArea.setLineWrap(true); // 設置自動折行
        getContentPane().add(textArea, BorderLayout.CENTER);// 添加文本域組件到文本框
        startBtn = new Button("開始");
        pauseBtn = new Button("暫停");
        resumeBtn = new Button("恢復");
        startBtn.addActionListener(this);
        pauseBtn.addActionListener(this);
        resumeBtn.addActionListener(this);
        panel = new Panel();
        panel.add(startBtn);
        panel.add(pauseBtn);
        panel.add(resumeBtn);
        getContentPane().add(panel, BorderLayout.SOUTH);
        setBounds(0, 0, 383, 225); // 設置窗體大小位置
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true); // 顯示窗體
    }

    /**
     * Runnable介面方法,是線程的執行方法
     */
    @Override
    public void run() {
        textArea.setText("\t");
        String[] intros = introduction.split(""); // 將字元串分割為數組
        for (String ch : intros) { // ForEach遍歷字元串數組
            while (!move) {
                try {
                    synchronized (this) {
                        wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            textArea.append(ch); // 添加一個字元到文本域
            try {
                Thread.sleep(100); // 線程休眠0.1秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        startBtn.setEnabled(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == startBtn) {
        	thread =new Thread(this);
			thread.start();
			move=true;
			startBtn.setEnabled(false);

        } else if (e.getSource() == pauseBtn) {
        	move=false;
        } else if (e.getSource() == resumeBtn) {
        	move=true;
        	synchronized (this) {
				notifyAll();
			}
        }
    }
}

程式運行截圖

自己截圖粘貼進markdown

實驗總結

這個實例體現了Java多線程編程的線程式控制制特性,通過線程的控制實現了動畫效果的實時調整。
Java多線程編程非常重要,能夠提高程式運行效率,但同時也需要註意線程之間的協作和控制,避免死鎖。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • jsonp 是前端一種用來解決網站跨域的技術,利用script標簽不受同源策略影響的特性引入一個非同源的js文件,並定義一個回調函數來接收數據,這樣就可以實現跨域獲取數據了,例如: 現在有一個鏈接返回的數據是這樣的: cb({ "name": "swk", "age": 18 }) 這是一個標準的j ...
  • JavaScript 中的記憶體泄漏是指程式中使用的記憶體不再被需要卻沒有被釋放,最終導致瀏覽器或者 Node.js 進程使用的記憶體越來越大,直到程式崩潰或者系統運行緩慢。 在 JavaScript 中,記憶體泄漏通常是由於變數、對象、閉包、事件監聽器等長期存在而沒有被釋放引起的。這些長期存在的引用會阻止 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 為了讓頁面保活更加穩定,你們是怎麼做的? 我用一行配置實現了 Vue頁面保活是指在用戶離開當前頁面後,可以在返回時恢覆上一次瀏覽頁面的狀態。這種技術可以讓用戶享受更加流暢自然的瀏覽體驗,而不會被繁瑣的操作打擾。 為什麼需要頁面保活? 頁面 ...
  • 1. 什麼是C#組合模式? 組合模式是一種結構型設計模式,它允許將對象組合成樹形結構以表示“整體/部分”層次結構。使用此模式,客戶端可以按相同的方式處理單個對象和對象集合,而不必關註它們是單個對象還是組合對象。組合對象本身也可以作為容器,包含其他組合對象,形成更複雜的樹形結構。 在C#中,組合模式是 ...
  • 本文翻譯自國外論壇 medium,原文地址:https://medium.com/@pradeesh-kumar/how-to-become-a-good-backend-engineer-9da75202a104 讓我們一起看看國外開發者認為優秀後端工程師需要掌握哪些技能。 誰是後端工程師? 本質 ...
  • 第1關:位元組輸入/輸出流實現數據的保存和讀取 package step1; import java.io.\*; import java.util.\*; public class SortArray { public static void main(String[] args) { _/\*\* ...
  • 本文首發於公眾號:Hunter後端 原文鏈接:Django筆記三十九之settings配置介紹 這一篇筆記介紹 Django 里 settings.py 里一些常用的配置項,這些配置有一些是在之前的筆記中有過介紹的,比如 logging 的日誌配置,session 的會話配置等,這裡就只做一下簡單的 ...
  • redis-主從模式弊端: 一、master節點異常shutdown後,從機原地待命,從機數據可以查詢(不可以寫入),等待主機重啟歸來 二、複製延時,信號衰減 redis-哨兵監控: 是什麼? 哨兵即為吹哨人,可以巡查監控後臺master主機是否故障,如果故障可以根據投票數自動將一個從庫轉換為新的m ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...