在corejava的课程中,有一个重要的知识点,就是线程。 java
那什么是线程呢?线程,是“进程”中某个单一顺序的控制流。而进程和流程的最大区别就在于,每一个进程都会独享一块存储区域,多个线程只能共享此进程的这块存储区域。 dom
那线程会给咱们的java程序带来什么好处呢?好处一,能够实现并行,好处二,能够更有效的利用资源。 学习
下面咱们就编写一个小小的赛跑游戏来看看线程给咱们程序带来的惊喜吧。 this
首先,我们先看看程序最后完成的效果,及操做流程: spa
游戏一开始将直接进入主题,简洁的界面,无需说明文档,一眼便知如何操做。(见图1)
线程
图1:游戏一开始的界面 对象
选择好咱们要支持的运动员后,点击肯定按钮,此时游戏尚未开始,但咱们已不可再改变支持的对象了。(见图2) 继承
图2:下注后的界面 接口
好吧,既然不能更改,那么就让比赛快点开始吧!“蜗牛,加油!加油!”(见图3) 游戏
图3:游戏开始后的界面
哦也!蜗牛赢了!看到了吗,结果就在图4里,哈哈哈,点击肯定后,400分就拿到手了!
图4: 出结果后的界面
真是一场痛快的比赛!
如今,我们来进行一下赛后分析,上面这个小游戏究竟有多少个线程呢?我听到有人说“这个很容易就看出来了,一共就3个吗,每一个参赛的跑者,都是一个线程”。真的只是表面看到的这样吗?
这个程序一共有5个线程!
不信吗?那听我来讲说:第1个线程,就是被你们忽略了,却有很是熟悉的main。这个是咱们java 程序运行时,一定会运行的,也是咱们学习java时最先接触的一个线程。第2、3、4个 线程,就是你们说的,那三个赛跑者,每个都是一个独立的线程。第5个线程,从图上是看不到的,却又是一个很是重要的线程,它甘居幕后,担任着发令,裁决输赢的任务,咱们暂且把它叫作“裁判”吧。
整个游戏的过程咱们了解了,所包含的线程咱们也都分析了,下面的时间就是着手实现的阶段了:
打着MVC的旗号,项目结构成了下面这个样子:
images:中放置着,程序所须要的所有图片
vo:里放着咱们的一个实体类
enter:里存放着程序的入口
view:里存放着程序的界面
control里存放着“裁判”类和监听器。
界面部分的编写我就不细说了,就是要继承JFrame来定义咱们本身的窗体。顺便说一句,那个跑道是经过画图绘制的背景。别忘了给按钮添加监听器哦!
今天的主题是线程,那么咱们就要仔细看看线程的代码了:
java中实现线程的有两种途径,一种是继承Thread类,还有一种是实现Runnable接口。下面的关于 “运动员”、”裁判”的实现,我都统一使用了第二种方法,就是实现Runnable接口。具体代码以下:
package saipao.vo;
import java.awt.Image; import java.awt.Point; import java.util.Random;
import javax.swing.ImageIcon;
public class Runners implements private private private private private private private /* * 名称、坐标、图片,小图标是只读的,只有get方法 * */
public return } public this.flag } public return } public return } public return } public return }
public this.win }
public return } public this.isRun } public super(); this.name this.weiZhi=new this.imgBig=new this.imgSmall=new this.isRun=true;
}
//退到起点 public this.weiZhi.move(0, this.flag=this.win=false; this.isRun=true; } //是否押对了 public return }
public Random while(this.isRun){ int x+=rd.nextInt(10)+1; this.weiZhi.move(x,(int)this.weiZhi.getY()); try Thread.sleep(100); } // e.printStackTrace(); } }
}
} |
好了,运动员的代码咱们看到了,你发现了Runnable接口中声明了几个方法了吗? 答对了,就一个叫作Run的方法。当线程启动后,就将会执行Run方法中的代码。知道执行完毕退出run方法,此线程就死亡了。
光有运动员,没有裁判怎么行!
package saipao.control;
import java.util.Vector;
import javax.swing.JOptionPane;
import saipao.view.MainFrame; import saipao.vo.Runners;
/* * 裁判类,用来肯定是否有到达终点的赛跑者 * */ public class CaiPan implements Thread [] thread; MainFrame mf; public super(); this.vt this.width this.mf=mf; }
//运动员开始跑
//判断是否有人到达重点 public //调用开跑方法 this.startRun(); //判断是否有运动员到达终点 while(vt.get(0).isRun()){ mf.lblWeiZhi(); for(int int if(x>=this.width){ vt.get(i).setWin(true);//设置当前运动员赢了 //并通知全部运动员都不用再跑了 for(int vt.get(j).setRun(false); } //退出判断是否到达终点的循环 break; } } } //赛跑结束,判断是输仍是赢,并计算金额 boolean for(int if(vt.get(i).isWiner()){ flag=vt.get(i).isWiner(); break; } } if(flag){ JOptionPane.showMessageDialog(mf,
}else{ JOptionPane.showMessageDialog(mf, } mf.changeMoney(flag); mf.btnKongZhi(2, }
} |
有没有注意到,Runnable接口仅仅是提供了线程启动后要调用的功能(run),并无提供启动线程的功能。要想真正的使线程运行起来,仍是要经过Thread的帮助,由于Thread类中提供了启动线程的start()功能。
剩下的就是在对应的监听事件中,命令咱们的裁判发号施令,开始咱们的比赛了。
在和你们说byebye以前,还想请你们思考一下,运动员(Runners)那个类除了经过实现Runnable接口来编写线程程序,还有没有别的方式,使其成为线程?若是有,那么会不会影响咱们其余类的代码呢?
当即动手吧!我会一直期待着你的答案哦!
做者:中软卓越天津ETC