前几天用多线程实现了创建小球并移动,想到大鱼吃小鱼,便突发奇想要写一个大球吃小球。首先第一步自然是先把界面弄好啦

 public class BallUI extends JPanel {

     private ArrayList<Ball> li = new ArrayList<Ball>();

     public static void main(String[] args) {
BallUI bu = new BallUI();
bu.UI();
} public void UI() {
JFrame jf = new JFrame();
jf.setLocationRelativeTo(null);
jf.setResizable(false);
jf.setSize(700, 700);
this.setSize(jf.getWidth(),jf.getHeight());
jf.setTitle("大球吃小球"); this.setPreferredSize(new Dimension(jf.getWidth(), jf.getHeight()));
jf.add(this); jf.setVisible(true);
} }

界面写好后想想要怎么做呢?既然是大球吃小球还利用线程,那肯定需要一个队列,然后呢?既然要队列,那队列里存什么?肯定存小球啊,那自然要创建一个小球类了,那小球有什么属性呢?坐标、移动速度、大小、颜色,除了这些在创建时还需不需要传些什么参数呢?既然传了颜色,那肯定需要画小球,我们在哪画?是调用方法还是在线程中获取小球属性然后画?我觉得调用方法会更好,所以我们要在这里传入一个画布。同样在后面我们还需要检测小球是否碰撞,因此我们还需要传入一个队列。下面便是Ball类的构造了

public class Ball {
private int size;
private int x;
private int y;
private int speedX;
private int speedY;
private Color c;
private JPanel jf;
private ArrayList<Ball> li; public Ball(int size, int x, int y, int speedX, int speedY, Color c, JPanel jf, ArrayList<Ball> li) {
this.size = size;
this.x = x;
this.y = y;
this.speedX = speedX;
this.speedY = speedY;
this.c = c;
this.jf = jf;
this.li = li;
}
  //画球
public void draw(Graphics g) {
}
  //移动球
public void move() {
}
  //清除上次留下的痕迹
public void clear(Graphics g) {
}
  //碰撞检测
public void crash(Graphics g) { }
}

创建好小球类后,我们便需要线程来创建小球、改变小球,那这里也有一个问题,我们是用一个线程还是两个还是多个?这样看,如果只用一个线程,那么我们每次改变小球得在创建了一个小球后进行,如果小球数量少还没问题,但是当小球数量多了之后,每便利一次就会用上一段时间,那么肯定会有延时,所以我们需要把这里分成两个线程,一个线程创建小球,一个线程改变小球。这里其实就利用了生产者消费者模型: 生产者负责生产数据并存入缓冲区,消费者从缓冲区中取出数据并且处理并输出。

 public class ThreadBall extends Thread {

     private ArrayList<Ball> li;
private JPanel jp;
private Graphics g; public ThreadBall(ArrayList<Ball> li,JPanel jp) {
this.li = li;
this.jp=jp;
} public void run() {
g=jp.getGraphics();
while(true) {
for(int i=0;i<li.size();i++) {
Ball ball=li.get(i);
ball.clear(g);
ball.crash(g);
ball.move();
ball.draw(g);
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} }
public class BallLis extends Thread {
private ArrayList<Ball> li = new ArrayList<Ball>();
private JPanel jp; public BallLis(ArrayList<Ball> li,JPanel jp) {
this.li = li;
this.jp = jp;
} public void run() {
while (true) {
int size = new Random().nextInt(30) + 10;
int x = new Random().nextInt(jp.getWidth());
int y = 0;
int speedX = new Random().nextInt(10) + 10;
int speedY = new Random().nextInt(10) + 5;
Color c=new Color(new Random().nextInt(256),new Random().nextInt(256),new Random().nextInt(256)); Ball bl=new Ball(size,x,y,speedX,speedY,c,jp,li);
li.add(bl); try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} }
} }

创建好线程后肯定需要在BallUI类中创建对象啦

        BallLis ball = new BallLis(li,this);
ball.start();
ThreadBall tb=new ThreadBall(li,this);
tb.start();

那么,剩下的任务就是实现小球类中的方法了,就留给你们去实现了。

注:代码已上传至github:https://github.com/leo6033/Java_Project

JAVA 多线程制作大球吃小球 一、实现球的自动生成及运动 生产消费模型的更多相关文章

  1. Java多线程读取大文件

    前言 今天是五一假期第一天,按理应该是快乐玩耍的日子,但是作为一个北漂到京师的开发人员,实在难想出去那玩耍.好玩的地方比较远,近处又感觉没意思.于是乎,闲着写篇文章,总结下昨天写的程序吧. 昨天下午朋 ...

  2. java——多线程知识点大总结

    1:理解线程的概念之前,我们有必要先理解一下进程的概念 程序(Program)是为实现特定目标或解决特定问题而用计算机语言(比如Java语言)编写的命令序列的集合. 进程指一个程序的一次执行过程   ...

  3. java多线程制作计时器

    基本思路: 在类中创建thread 供按钮监听器调用. 界面设计:

  4. Java多线程总结之线程安全队列Queue

    在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列.Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非 ...

  5. java多线程之队列

    1.注:先不看阻塞与否,这ReentrantLock的使用方式就能说明这个类是线程安全类. 2.线程安全的类,BlockingQueue,ConcurrentLinkedQueue.这些都是线程安全的 ...

  6. java 多线程 22 :生产者/消费者模式 进阶 利用await()/signal()实现

    java多线程15 :wait()和notify() 的生产者/消费者模式 在这一章已经实现了  wait/notify 生产消费模型 利用await()/signal()实现生产者和消费者模型 一样 ...

  7. Java多线程学习(一)

    在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列.Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非 ...

  8. 【java】Java多线程总结之线程安全队列Queue【转载】

    原文地址:https://www.cnblogs.com/java-jun-world2099/articles/10165949.html ============================= ...

  9. java 多线程 19: ReentrantLock 与 Condition

    ReentrantLock ReentrantLock,一个可重入的互斥锁,它具有与使用synchronized方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大. Reentran ...

随机推荐

  1. OpenStack 网络服务 Neutron 私有网络构建(十九)

    本章内容基于之前提供者网络构建的基础上进行改动,之前文章参考如下: Openstack 网络服务 Neutron介绍和控制节点部署 (九) Openstack 网络服务 Neutron计算节点部署(十 ...

  2. python---django初步了解以及安装(包括Django网页首次无法访问的原因及解决方法,以及在linux服务器上布置无法启动的原因)

    pip install Django 相关网站资源: Python下有许多款不同的 Web 框架.Django是重量级选手中最有代表性的一位.许多成功的网站和APP都基于Django. Django是 ...

  3. Codeforces 314 E. Sereja and Squares

    http://codeforces.com/contest/314/problem/E 题意: 原本有一个合法的括号序列 擦去了所有的右括号和部分左括号 问有多少种填括号的方式使他仍然是合法的括号序列 ...

  4. Django 2.0.1 官方文档翻译: 编写你的第一个 Django app,第一部分(Page 6)

    编写你的第一个 Django app,第一部分(Page 6)转载请注明链接地址 Django 2.0.1 官方文档翻译: Django 2.0.1.dev20171223092829 documen ...

  5. HDU 2086 A=? 数学题

    题目描述:有一个公式,Ai = (Ai-1 + Ai+1)/2 - Ci (i = 1, 2, 3, .... n).,如果给出A0, An+1, 和 C1, C2, .....Cn要你计算出A1是多 ...

  6. org.hibernate.TransientObjectException异常

    代码如下: /** * 测试4:新增一个秘书角色,并赋给张三该角色 */ @Test public void test4(){ Session session = HibernateUtils.ope ...

  7. House Robber I & II & III

    House Robber You are a professional robber planning to rob houses along a street. Each house has a c ...

  8. DOM事件阶段以及事件捕获与事件冒泡先后执行顺序

    平时浏览这么多技术文章,如过不去实践.深入弄透它,这个技术点很快就会在脑海里模糊.要加深印象,就得好好过一遍.重要的事情说三遍,重要的知识写一遍. 开发过程中我们都希望使用别人成熟的框架,因为站在巨人 ...

  9. NOIp 2018 提高组

    T1铺设道路 传送门 题目描述 春春是一名道路工程师,负责铺设一条长度为 $ n $ 的道路. 铺设道路的主要工作是填平下陷的地表.整段道路可以看作是 $ n $ 块首尾相连的区域,一开始,第 ii ...

  10. java 组合接口时的名字冲突

    重载方法仅通过返回类型是区分不开的,在打算组合的不同接口中,尽量使用不同的方法名,否则可能导致混乱 //: interfaces/InterfaceCollision.java package obj ...