多线程总结

1.进程,程序的区别

在上一篇总结中总结了进程与线程的区别,现在来看进程与程序的区别。上一篇总结中已经提到进程是程序在处理机中的一次运行,所以进程是暂时的,程序是永久的。进程有并发性,而程序没有;一个进程可以执行一个或多个程序,同样,一个程序可被多个进程执行。

2.线程的创建方式

在上一篇总结中介绍了线程的一种创建方式,即通过继承Thread类,重写父类run()方法,通过start()方法启动线程。现在总结另外一种线程的创建方式,即通过实现Runnable接口来创建,与第一种创建方法一样,重写父类run()的方法,只是在启动线程时不同,比如定义类public class Listener implements Runnable{ },然后要实例化Listener类对象,比如:
Listener lt = new Listener(); 然后通过Thread thread = new Thread(lt)这一句创建的thread对象来调用start()方法启动。

3.线程的监听模式

在上一篇总结总结中通过作多线程一个了简单的弹球游戏,该游戏只是解决了球碰到边弹回的问题,球与球碰撞的问题并没有解决。这里通过线程的监听模式解决此问题,该模式要求球不要太多,否则会出问题。前面是实例化了两个Ball类对象的,要实现线程的监听,首先要实例化一个Ball类型的队列,将Ball类的对象加到队列中。然后再增加一个监听进程,该进程的作用是每次取出队列中的两个元素,分别得到它们外切正方形左上角的坐标,再分别和其它元素两两比较判断两个球外切正方形左上角的坐标的距离是否小于或等于它们的半径之后,如果小于它们的半径之和,则说明两个小球碰撞了,则要改变它们的增量,使它们弹回。具体代码如下:

public class Listener extends Thread{

public ArrayList<Ball> list;

public Listener(ArrayList<Ball> list){
this.list = list;
}


public void run(){

while (!Ball.isStop){

while(!Ball.isPause){
//遍历队列
for (int i=0;i<list.size()-1;i++){

Ball b1 = list.get(i);
Ball b2 = list.get(i+1);
System.out.println(b1.x0+" "+b1.y0+"<>"+b2.x0+" "+b2.y0);


if(Math.sqrt((b1.x0-b2.x0)*(b1.x0-b2.x0)+(b1.y0-b2.y0)*(b1.y0-b2.y0))<=30){
b1.x = -b1.x;
b1.y = -b1.y;
b2.x = -b2.x;
b2.y = -b2.y;

}


}

try{
Thread.sleep(50);
}catch(Exception ep){
ep.printStackTrace();
}

}

try{
Thread.sleep(1);
}catch(Exception ep){
ep.printStackTrace();
}


}


}


}

在按钮监听器那边再启动此线程就可以解决两个小球判断的问题了,但是这种方法还是有很大的问题,如果你有更好的方法,请赐教!!

4.线程的控制

线程的控制主要是暂停线程,继续线程和停止线程。还是以上面作的弹球游戏为例,总结线程的控制。首先要在Ball类里面定义两个boolean型的静态变量:isStop和isPase,且默认值都为false。然后在小球移动的move();方法里面增加一个while循环,具体代码如下:
//小球移动的方法
public void move() {

while(!isStop){

while(!isPause){

//清除图像
g.setColor(blf.getContentPane().getBackground());
g.fillOval(x0,y0,30,30);

if (x!=0){
if (x0<=8||x0>=491){//左右两壁
x=-x;
}else if (y0<=30||y0>=591){//上下两壁
y=-y;
}elseif((x0<=8&&y0<=30)||(x0<=8&&y0>=591)||(x0>=491&&y0<=30)||(x0>=491&&y0>=591)){//垂直碰撞四壁
x=-x;y=-y;
}

g.setColor(Color.RED);
g.fillOval(x0+=x,y0+=y,30,30);

}

try{
Thread.sleep(50);
}catch(Exception ep){
ep.printStackTrace();
}


}

try{
Thread.sleep(1);
}catch(Exception ep){
ep.printStackTrace();
}

}

}

然后再在窗体类那边添加一个“停止”的按钮,用String command = e.getActionCommand();语句得到按钮上的字符串。再根据得到的字符串是否是等于“开始”,如果等于,则启动前面的两个进程,setText("暂停");语句改变按钮上的字为“暂停”,当得到的字符串等于“暂停”,则把按钮上的字改为“继续”,如果得到的字符串等于“继续”,则把按钮上的字改为“暂停”,如果得到的字符串等于“停止”,则把“暂停”按钮改为“开始”,具体代码如下:
//匿名内部类,动作监听器
ActionListener atl = new ActionListener(){

public void actionPerformed(ActionEvent e){

String command = e.getActionCommand();

if (command.equals("开始")){

Listener lt = new Listener(list,BallFrame.this);
lt.start();


Ball b = new Ball(BallFrame.this);
b.start();
list.add(b);

Ball b1 = new Ball(BallFrame.this);
b1.start();
list.add(b1);

bt.setText("暂停");

}

if (command.equals("暂停")){

bt.setText("继续");
}

if (command.equals("继续")){

bt.setText("暂停");
}

if (command.equals("停止")){

bt.setText("开始");
}

}


};

要实现线程的暂停,继续和结束,就要在Ball类里面各自定义静态方法改变isStop和isPause的值而使move()里面的两个循环停止与开始就可以了,具体代码如下:
//暂停的方法
public static void pauseThread(){
isPause=true;
}

//继续的方法
public static void resumeThread(){
isPause=false;
}

//停止的方法
public static void stopThread(){
isPause=true;
isStop=true;
}

//初始的方法
public static void initThread(){
isPause=false;
isStop=false;
}

然后再在监听器那边直接调用这些方法就行了,如下代码所示:
//匿名内部类,动作监听器
ActionListener atl = new ActionListener(){

public void actionPerformed(ActionEvent e){

String command = e.getActionCommand();

if (command.equals("开始")){

Ball.initThread();

Listener lt = new Listener(list,BallFrame.this);
lt.start();


Ball b = new Ball(BallFrame.this);
b.start();
list.add(b);

Ball b1 = new Ball(BallFrame.this);
b1.start();
list.add(b1);

bt.setText("暂停");

}

if (command.equals("暂停")){
Ball.pauseThread();

bt.setText("继续");
}

if (command.equals("继续")){

Ball.resumeThread();
bt.setText("暂停");
}

if (command.equals("停止")){

Ball.stopThread();
bt.setText("开始");
}

}


};
至此,通过两个按钮就可以实现线程的暂停、继续与结束,从而使小球暂停移动、继续移动和重新开始。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值