第十一课时 多线程
要理解多线程,就要从进程的概念开始理解,什么是进程?一个程序就是进程吗?答案是错误的,所谓进程,简单通俗的讲就是一个跑起来
的程序。进程需要两个条件,一是程序,二是资源。
那么什么又是进程呢?打个比方,比如我去搬书这件事是一个进程,那么线程就好比人数,人越多,完成的速度也越快。线程就是这样。
其实在早期,计算机是无法实现真正意义上的线程的,因为cpu只有一个,一次也只能执行一行代码。所以程序员就把代码分成一个个时间片
,cup就不断地从这代码上切换,由于切换速度很快,就给人造成一种假象,好像同时在完成,其实不是,如今的硬件已经可以实现真正意义
上的线程了。(注意一点,每个进程至少有一个线程)
java中多线程的实现:
java不像c或c++那样使用线程还需要调用系统api那样麻烦,java只要继承Thread或者实现Runnable接口,就能启动线程
public class Test1() extends Thread{
public static void main(String[] args){
Test1 test = new Test1();
test.start();//不用自己调用run方法,只要启动线程,系统会自己调用
}
public void run(){
.....
}
}
public class Test2() implements Runnable{
public static void main(String[] args){
Test2 test = new Test1();
Thread thread = new Thread(test);
thread.start();
}
public void run(){
.....
}
}
注意一点,线程的确是能够快速提高效率,但是也难以控制,就像开车一样,速度越快,事故发生的可能就越大,所以如果在计算比较精确
的数值时,如果线程不太会用的话,那就不要用了
实例:两小球的碰撞与边界的碰撞,本例只实现了两个小球的碰撞,如果想实现多个小球的碰撞有两个方法,第一是在paint()方法里调用
小球的碰撞方法,第二是再写一个碰撞类,一个碰撞一个线程,这里我就不演示了,有兴趣的同学自己试一下。
package cn.czm0725线程;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
/**
* 窗体类
* @author ChenZhaoMin
*
*/
public class BallFrame extends JFrame{
private Ball ball;
private Ball ball2;
/**
* @param args
*/
public static void main(String[] args) {
BallFrame bf = new BallFrame();
bf.initUI();
}
public void initUI(){
this.setTitle("小球碰撞");
this.setSize(600,600);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(3);
this.setVisible(true);
ball = new Ball(this,Color.RED,20,30,30,95);
Thread t1 = new Thread(ball);
t1.start();
ball2 = new Ball(this,Color.BLUE,500,500,30,315);
Thread t2 = new Thread(ball2);
t2.start();
ball.setB(ball2);
ball2.setB(ball);
}
public void paint(Graphics g){
super.paint(g);
Graphics2D g2= (Graphics2D)g;
//ball.collide(ball2);调用碰撞也可以实现
g2.setColor(ball.getC());
ball.setFrame(ball.getX(), ball.getY(), ball.getDiameter(), ball.getDiameter());
g2.fill(ball);
g2.setColor(ball2.getC());
ball2.setFrame(ball2.getX(), ball2.getY(), ball2.getDiameter(), ball2.getDiameter());
g2.fill(ball2);
}
}
package cn.czm0725线程;
import java.awt.Color;
import java.awt.geom.Ellipse2D;
/**
* 小球类
* @author ChenZhaoMin
*
*/
public class Ball extends Ellipse2D.Double implements Runnable {
private BallFrame bf;
private Color c;
private double x, y, diameter;
private double speed = 2;
private int alpha;//与竖向顺时针夹角
private Ball b;
public Ball(BallFrame bf, Color c, double x, double y, int diameter,int alpha) {
this.bf = bf;
this.c = c;
this.x = x;
this.y = y;
this.diameter = diameter;
this.alpha=alpha;
}
/**
* 重写run方法
*/
public void run() {
while (true) {
move();
collide(b);
bf.repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 小球的方法(包括与边界的碰撞)
*/
public void move() {
x += speed * Math.sin(alpha * Math.PI / 180);
y -= speed * Math.cos(alpha * Math.PI / 180);
if (x < 15 || x > 570)
alpha = 360 - alpha;
if (y < 30 || y > 560)
alpha = 180 - alpha;
}
/**
* 小球碰撞的方法
* @param b所要碰撞的小球
*/
public void collide(Ball b){
if(Math.sqrt(Math.pow((this.x-b.x),2)+Math.pow((this.y-b.y),2))<(this.diameter/2+b.diameter/2)){
if(Math.sin(this.alpha*Math.PI/180)>0){
this.alpha=this.alpha+180;
}else{
this.alpha=this.alpha-180;
}
if(Math.sin(b.alpha*Math.PI/180)>0){
b.alpha=b.alpha+180;
}else{
b.alpha=b.alpha-180;
}
}
}
public Color getC() {
return c;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getDiameter() {
return diameter;
}
public void setB(Ball b) {
this.b = b;
}
}