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;
}
}
}
}
}
}
这是一个很简单的多线程小程序,小小娱乐~