入手多线程第二站-生产消费模型(Java)

之前的例子,每画一个小球,就要启动一个线程,这是十分浪费的,其实只需要 2 个线程:
第 1 个线程,不停的在界面上画小球的位置
第 2 个线程,不停地改小球的坐标
以上两个线程共享存放小球的队列,鼠标每点击一次,就向队列中存入一个小球。
这就是个典型的 “生产—消费” 模型,我们将编写 5 个类来实现,看先概要:
1.子弹类,封装了自己的绘制、移动策略,将在鼠标松开进创建,存进共享队列。
2.移动线程:只负责每 20ms,从共享队列中每个子弹移动一次。
3.绘制队列:只负责每 20ms,清屏,再将共享队列中每个子弹画一次。
4.鼠标监听器类:响应鼠标松开事件时,创建子弹对象,存进共享队列
5.界面主控类:创建一个共享队列对象(java.util.ArrayList 类,可理解为一个变长数组),传给鼠标监听器对象、传给上面的移动线程对象、绘制线程对象 并启动这两个线程对象。
下面展示具体代码:
第 1:编写一个子弹类:
//字弹类
public class Bullet {
public int x,y;//子弹的坐标
public int r=30; //子弹大小
public Bullet(int x,int y){//创建子弹时初始化坐标
this.x=x;
this.y=y;
  }
public void move() {//子弹自己的移动策略
x+=2;
  }
public void draw(Graphics g) {//将自己在界面上画出的策略
g.setColor(Color.GREEN);//设成自己的颜色
g.fillOval(x, y, r, r);
  }
}
第 2: 编写画子弹的线程,代表生产者类
//生产消费模型:每 10m,清屏,把队列中的子弹画出来
public class ThreadDraw extends Thread {
private ArrayList<Bullet> bs;// 指向存队子弹的队列
private Graphics g;// 界面的画布
public ThreadDraw(ArrayList<Bullet> bs, Graphics g) {
this.bs = bs;// 创建时,传入共享队列和画布
this.g = g;
}
public void run() {//线程从这里启动
while (true) {
for (int i = 0; i < bs.size(); i++) {
Bullet b = bs.get(i);//把队列中的子弹画一遍
b.draw(g);
}
try { Thread.sleep(20);} catch (Exception ef) { }
g.setColor(Color.WHITE);//清屏
g.fillRect(0, 0, 1200, 800);
    }
  }
}
第 3: 编写移动子弹的线程,代表生产者类
//每过 10s,移动一次队列中每个子弹的坐标
public class ThreadMove extends Thread {
private ArrayList<Bullet> bs;//指向存队子弹的队列
public ThreadMove(ArrayList<Bullet> bs){
this.bs=bs;
}
public void run(){
while(true){
for(int i=0;i<bs.size();i++){//移动队列中每个子弹
Bullet bullet=bs.get(i);
bullet.move();//移动
}
try{ Thread.sleep(40); }catch(Exception ef){}
    }
  }
}
第 4: 鼠标监听器类,在界面上松开时,创建一个子弹对象放入队列
//鼠标点击时,放入子弹
public class MouseLis extends MouseAdapter {
private ArrayList<Bullet> bs;//存放子弹的队列, 指向界面的共享队列
public MouseLis( ArrayList<Bullet> bs){
this.bs=bs;
}
public void mouseReleased(MouseEvent e){
Bullet bu=new Bullet(e.getX(),e.getY());
this.bs.add(bu); //生成一个子弹,放进队列
  }
}
第 5:界面类,界面类像个主板,总装了以上对象
//飞机大战界面 .生产消费模型
public class FlyWar extends JFrame {
//全局存放子弹的队列:将传入到生产,消费线程对象中
private ArrayList<Bullet> bs = new ArrayList();
public void initUI() {
this.setTitle("生产消费模型的飞机大战");
this.setSize(1600, 400);
this.setDefaultCloseOperation(3);
this.setVisible(true);
Graphics g = this.getGraphics();
MouseLis ms = new MouseLis(bs);//监听器对象:传入共享队列
this.addMouseListener(ms);
ThreadMove tMove = new ThreadMove(bs);//传入共享队列
tMove.start();// 移动的线程启动
ThreadDraw tDraw = new ThreadDraw(bs, g);//传入共享队列
tDraw.start();// 画的线程启动
}
// 主函数
public static void main(String[] args) {
FlyWar db = new FlyWar();
db.initUI();
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值