java学习之多线程——小球碰撞

1、多线程安全问题:多个线程同时处理共享资源所导致的。

2、判断程序是否有线程安全问题的依据:

        A.是否有多线程环境;

        B.是否有共享数据;

        C.是否有多条语句操作共享数据

3、同步机制:用来解决线程安全问题

        A.同步代码块:
            synchronized(lock) {
           操作共享资源代码块;
            }
                      
        B.同步方法:
            synchronized 返回值类型 方法名(参数列表){}

4、多线程通讯:

     A. void wait():使当前线程放弃同步锁,进入等待; 

     B. void notify():唤醒此同步锁第一个调用wait()的线程;

     C. void notifyAll():唤醒此同步锁上调用wait()方法的所有线程;

5、小球碰撞:          

    功能实现:

   A、按钮控制线程开停;

   B、一个线程控制多个小球;

   C:球到边界自动弹回及小球之间能互相碰撞;

代码实现:

主界面:

package com.Liao.ball0704v2;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;

public class MainUI extends JFrame {
    
    private static final long serialVersionUID = 1L;
    
    public static void main(String[] args) {
            new MainUI().init();
     }
    public void init(){
        this.setTitle("小球碰撞");
        this.setSize(700, 700);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(3);
        this.setLayout(new FlowLayout());
        this.getContentPane().setBackground(Color.WHITE);
        this.setResizable(false);
        //控制按钮
        JButton jbu=new JButton("开始");
        jbu.setPreferredSize(new Dimension(120,40));
        this.add(jbu);
        
        this.setVisible(true);
        Graphics g=this.getGraphics();
        //创建监听器
        DrawListener dl=new DrawListener(g,jbu);
        this.addMouseListener(dl);
        jbu.addActionListener(dl);
    }
}

监听器:获取小球坐标

package com.Liao.ball0704v2;

import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;

public class DrawListener extends MouseAdapter implements ActionListener {
	private ThreadBall tb;
	private Ball[] ballArray = new Ball[100];
	//存储每个小球的位置
	private int[] xArray = new int[100];
	private int[] yArray = new int[100];
	//存储每个小球的速度
	private int[] dxArray = new int[100];
	private int[] dyArray = new int[100];
	private int index = 0;
	private Graphics g;
	private Boolean ispaused;
	private JButton jbu;

	public DrawListener(Graphics g, JButton jbu) {
		super();
		this.g = g;
		this.jbu = jbu;
	}

	public void actionPerformed(ActionEvent e) {
		String name = e.getActionCommand();
		if ("开始".equals(name)) {
			if (tb != null) {
				tb.restartTask();
			}
			jbu.setText("结束");
		}
		if ("结束".equals(name)) {
			tb.pauseTask();
			jbu.setText("开始");
		}
	}

	public void mouseClicked(MouseEvent e) {
		//获取当前点坐标
		xArray[index] = e.getX();
		yArray[index] = e.getY();
		//设定速度
		dxArray[index] = 5;
		dyArray[index] = 5;
		//存入球形数组
		Ball ball = new Ball(xArray, yArray, dxArray, dyArray);
		ballArray[index] = ball;
		index++;
		//启动线程
		if (tb == null) {
			ispaused=true;
			tb = new ThreadBall(g, ballArray, ispaused);
			tb.start();
		}
	}
}

小球线程:接收坐标,控制线程

package com.Liao.ball0704v2;

import java.awt.Graphics;

public class ThreadBall extends Thread {
	public Boolean ispaused;
	private Graphics g;
	private Ball[] ballArray;

	public ThreadBall(Graphics g, Ball[] ballArray, Boolean ispaused) {
		this.g = g;
		this.ispaused = ispaused;
		this.ballArray = ballArray;
	}

	public void pauseTask() {
		ispaused = true;
	}

	public void restartTask() {
		ispaused = false;
	}

	public void run() {
		while (true) {
			System.out.println(Thread.currentThread().getName());
			while (!ispaused) {
				// 延时
				try {
					Thread.sleep(50);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
				for (int i = 0; i < ballArray.length; i++) {
					Ball ball = ballArray[i];
					if (ball != null) {
						ball.draw(g, i);
					}
				}
			}
		}
	}
}

球类:绘制小球、控制小球运动及判断碰撞

package com.Liao.ball0704v2;

import java.awt.Color;
import java.awt.Graphics;

public class Ball {
    private int[] xArray, yArray, dxArray, dyArray;
    private int diaMeter = 50;

    public Ball(int[] xArray, int[] yArray, int[] dxArray, int[] dyArray) {
        this.xArray = xArray;
        this.yArray = yArray;
        this.dxArray = dxArray;
        this.dyArray = dyArray;
    }

    public void draw(Graphics g, int index) {
        int dx, dy;
        //绘制小球
        g.setColor(Color.white);
        g.fillOval(xArray[index], yArray[index], diaMeter, diaMeter);
        //小球运动
        xArray[index] += dxArray[index];
        yArray[index] += dyArray[index];
        g.setColor(Color.black);
        g.fillOval(xArray[index], yArray[index], diaMeter, diaMeter);

        if (xArray[index] >= 650 || xArray[index] <= 0) {
            dxArray[index] = -dxArray[index];
        }
        if (yArray[index] >= 650 || yArray[index] <= 0) {
            dyArray[index] = -dyArray[index];
        }
        //判断碰撞
        if (xArray.length > 1) {
            for (int i = 0; i < xArray.length; i++) {
                for (int j = i + 1; j < xArray.length; j++) {
                    if ((int) Math.hypot((xArray[i] - xArray[j]), (yArray[i] - yArray[j])) <= 50) {
                        dx = dxArray[i];
                        dy = dyArray[i];
                        dxArray[i] = dxArray[j];
                        dyArray[i] = dyArray[j];
                        dxArray[j] = dx;
                        dyArray[j] = dy;
                    }
                }
            }
        }
    }
}

   这是一个很简单的多线程小程序,小小娱乐~

猜你喜欢

转载自blog.csdn.net/LIAO_7053/article/details/81294868