Java学习记录:多线程编程实战

实验说明:实现模拟一个鸟笼,里面有20个鸟在其中自由移动(每个鸟是一个Thread类的子类,用一张图片表示鸟;笼子为Frame类子类),有三个按钮(start,stop,quit)操控笼子中鸟的行为,分别对应开始,暂停和退出程序

//Bird类
package CageAndBirds;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;


public class Bird extends Thread{
    
    private int xc = 2*(1 - 2*(int)Math.round(Math.random()));
    //Math.random给予随机数(0.0~1.0),Math.round将随机数化为整数(0~1),然后利用强制类型转换化为INT
    private int yc = 2*(1 - 2*(int)Math.round(Math.random()));
    //鸟的坐标变化
    private boolean running = false;
    private Cage cage = null;
    protected int x,y;//表示鸟此时位置
    Image bird = Toolkit.getDefaultToolkit().getImage("pg.jpg");
    
    public Bird(Cage _cage,int _x, int _y) {
        cage = _cage;
        x = _x;
        y = _y;
        start();
    }
    
    public void start() {
        running = true;
        super.start(); //将running的值修改后,再进行原来的资源分配操作(原资源分配操作可以在父类的start方法中可见)
    }
    
    public void halt() {
        running = false;
    }//停止运动
    
    public void run() {
        while(running) {//如果running的值为真就继续执行线程
            move();
            try {
                sleep(120);
            } catch (InterruptedException e) {
                
                System.err.println("Thread Interrupted");
            }
            cage.repaint(); //每次循环执行完毕都刷新地图
        }
    }

    private void move() {
        x += xc;
        y += yc;
        if(x > cage.getSize().width ) {
            x = cage.getSize().width; // 设置边界值
            xc *= -1; // 调换方向
        }
        
        if(x < 0) {
            x = 0;
            xc *= -1;
        }
        
        if(y > cage.getSize().height) {
            y = cage.getSize().height;
            yc *= -1;
        }
        
        if(y < 0){
            y = 0;
            yc *= -1;
        }
        
    }
    
    public void draw(Graphics g) {
        g.drawImage (bird,x,y,30,40,cage);
    }//将鸟的形象画在画布上
}

//Cage类
package CageAndBirds;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;


public class Cage extends Frame implements ActionListener{
    
    private Button quit =new Button("quit");
    private Button start =new Button("start");
    private Button stop =new Button("stop");
    private Bird birds[] =new Bird[20]; //用数组存储在笼子中的鸟
    Image bird = Toolkit.getDefaultToolkit().getImage("pg.jpg");    
    
    private class WindowCloser extends WindowAdapter{
        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }
    }
    
    //构造笼子
    public Cage() {
        super("Cage With Birds");
        setLayout(new FlowLayout());
        add(quit);quit.addActionListener(this);
        add(start);start.addActionListener(this);
        add(stop);stop.addActionListener(this);
        validate();setSize(1000, 1000);
        setVisible(true);
        addWindowListener(new WindowCloser());
        for(int i=0; i

实验结果展示:


Java学习记录:多线程编程实战_第1张图片
12345678.GIF

实验总结:

(1)此实验涉及到一个编程技巧,实现线程随时终止运行->增加一个bool变量running来控制run函数的运行,同时这个running可以在我们新定义的函数halt中进行修改。
(2)注意多线程程序的编写,我们定义的每一只bird都是一个线程,线程的几种状态如下:新建(Newborn)、就绪(Runnable)、阻塞(Blocked)、运行(Running)和死亡(Dead)。一个新的线程,通过start方法进入就绪等待序列,CPU资源充足则会直接执行run方法。
(3)注意paint方法和repaint方法的联合使用,一般来说,paint方法中定义具体paint的内容,然后再需要刷新的地方调用repaint方法(repaint会自动调用paint方法,paint不需要单独显式调用)

你可能感兴趣的:(Java学习记录:多线程编程实战)