Java第九课——多线程

Java第九课——多线程

首先先了解一下什么是多线程:

多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率。
通俗的说就是在同一时间做多个任务,他们之间不能有先后顺序,而是同时进行。

那么为什么要使用多线程呢?

举个例子,比如飞机大战游戏,假如按一下空格键就会发射一颗子弹,如果想实现子弹连发,就需要按下多次空格键。如果不使用多线程,就需要等上一个子弹飞出去了,完成了它应该要走的轨迹,下一颗子弹才会出发。使用多线程的话,二者执行没有影响,按下空格就会往发射子弹,子弹的先后顺序只取决于按下空格键的顺序,与上一颗子弹是否到终点无关。

那么如何实现多线程?

线程的实现的实质是通过继承Thread类或是实现Runnable接口,重写里面的run方法来实现,具体如何实现见下面例子
我们以画小球的移动为例:鼠标按下,小球向右”跑“,并且没有"先后顺序"
首先需要一个界面和一个监听器,并完成小球的移动

public class Frame{
	public void showUI(){
		JFrame frame=new JFrame();
		FlowLayout Layout=new FlowLayout();
		Listener l=new Listener();
		
   		frame.setSize(600,600);
		frame.setLocationRelativeTo(null);
		frame.setLayout(Layout);
		frame.addMouseListener(l);
		
		frame.setVisible(true);
		Graphics g=frame.getGraphics();
		l.g=g;
	}
	public static void main(String[] args) {
		Frame f=new Frame();
		f.showUI();
}
public class Listener implements MouseListener{
	private int x;
	private int y;
	Graphics g;
	public void mousePressed(MouseEvent e) {
		x=e.getX();
		y=e.getY();
		for(int i=0;i<200;i+=20){
			g.setColor(Color.BLACK);
			g.fillOval(x+i, y, 20, 20);
			try{//休眠100ms,使小球的轨迹可见
				Thread.sleep(100);
			}catch (Exception a){
			}
			g.setColor(new Color(238,238,238));
			g.fillOval(x+i, y, 20, 20);
		}
		//小球停下时的位置
		g.setColor(Color.BLACK);
		g.fillOval(x+200, y, 20, 20);
	}
}

上面的代码实现了基本的移动,并没有加入线程,所以当鼠标点击多个地方时,小球是一个一个出来的,而不是点下立刻就出来的。那么接下来加入线程

在加入之前先介绍一下队列:
ArrayList,队列类似于一个数组,用来存放数据,和数组一样这个数据可以是int,float,string或是类的对象。但区别是数组是在初始化时就固定了长度的,但队列不需要限制长度,就如同排队一样,一个接一个往后站。
初始化的方法是:
int类型:ArrayList< int > list = new ArrayList < int > ();
类的对象:ArrayList< Ball > list=new ArrayList< Ball >();

为了实现小球之间实现不影响,我们引入队列ArrayList,每次按下鼠标就会把一个小球放进队列,这样小球之间就没有先后执行的关系了。再然后,另外写一个控制小球的类,并继承Thread,这个类中线程的作用是从队列里面拿出小球,并调用封装好的小球的方法实现球的移动,这个类要写run方法用于启动线程。到这里就实现了每个小球互不影响

综上另外写两个个类,一个定义为小球类,包括小球本身的运动方法和画小球的方法;另一个类为控制小球的类,这个类要继承Thread。
小球类:包括自己的移动方法

public class Ball {
	private int x;
	private int y;
	Graphics g;
	public Ball(int x,int y,Graphics g){
		this.x=x;
		this.y=y;
		this.g=g;
	}
	public void move(){
		x+=20;
	}
	public void draw(){
		g.setColor(Color.BLACK);
  		g.fillOval(x, y, 20, 20);
		try{
			Thread.sleep(150);
		}catch(Exception e){
		}
		g.setColor(new Color(238,238,238));
		g.fillOval(x, y, 20, 20);
	}
}

BallControl类:继承Thread并写run方法

public class BallControl extends Thread{
	private ArrayList< Ball > list=new ArrayList< Ball >();
	public BallControl(ArrayList<Ball> list){
		this.list=list; 
	}
	public void run(){
		while(true){
			for(int i=0;i<list.size();i++){
				Ball b=list.get(i);
				b.move();
				b.draw();
			}
			try{
				Thread.sleep(15);
			}catch(Exception e){
			}
		}
	}
}

然后在Listener里面添加小球

public class Listener implements MouseListener{
	private int x;
	private int y;
	Graphics g;
	private ArrayList<Ball> list=new ArrayList<Ball>();
	public Listener(ArrayList<Ball> list){
		this.list=list;
	}
	@Override
	public void mousePressed(MouseEvent e) {
		x=e.getX();
		y=e.getY();
		Ball b=new Ball(x,y,g);
		list.add(b);
	}
]

最后只要在界面里启动线程就好了

public void showUI(){
	...//前面就省略了
	BallControl bc=new BallControl(list);
	bc.start();
}

最后实现效果可能并不好,没有加入缓存画布,具体内容在下下次课飞机大战的实现会讲解
另外,一种傻瓜式的线程方法Timer和TimerTask。
Timer是一个定时器,通过schedule(TimerTask task,long delay,long period)方法来使定时器工作,delay是指启动定时任务前的延迟,period是每过period时间就调用一次。
TimerTask是一个任务,需要在里面写run方法:

TimerTask task=new TimerTask(){
	public void run(){
	}
};//最后有有个分号

总的结构式:

Timer timer = new Timer();
TimerTask task=new TimerTask(){
 	public void run(){
	}
};
timer.schedule(task,1000,1000);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值