- 浏览: 5858 次
- 性别:
最初听闻“线程”这个词,是在那时候自己写的小程序存在着这样的诟病:触发按钮之后,监听器捕捉到用户操作,在其触发动作所执行的指令尚未结束前,按钮是会一直“凹下去”的,待到所有的指令运行结束之后,才会“弹起来”,只个时候才能再次点击按钮。听闻学习了线程之后就能解决这个问题。带着这样的好奇,走进了线程的学习。。。
在此之前,只听说过“进程”,“程序”,但到底什么是“线程”?。。。。。。通过学习,明白了原来每一个程序都会包含有一个或若干个进程,而每一个进程其实是由一个或若干个线程组成。线程,是程序执行流的最小单元,每一个线程就是一个进程的实体,线程本身不拥有系统资源,与同属一个进程的其他线程共同的享有着进程所拥有的资源,线程之间的关系:一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。
在java.util下面有一个叫Thread的类和一个叫Runnable的接口,解决问题的方式有两种:一,创建一个类来继承Thread类,并重写run()方法,然后实例化这个类的一个对象,通过调用start()方法来启动线程;二,定义一个接口来实现Runnable,并实现其run()方法,将所定义的接口作为Thread的构造方法的参数,最后再创建Thread类的对象并调用start()方法来启动线程。显然,第一种方式操作比较简单,就以它为例吧。
介绍了理论知识,该从代码着手了。我的理解其实很简单,那就是将之前所要运行的指令放入run()方法中即可。下面简单介绍弹球游戏开发:
很显然,这个游戏的实现要用到线程,思路是:随机生成的小球按照运动轨迹运动(球的起始位置,颜色,尺寸,运动方向以及速度在给定的范围内均是任意的),当小球接触到窗体的边框,运动方向按照“反射定律”发生相应的改变,小球之间接触到一起的时候会按照物理的碰撞原则弹开。
定义一个继承Thread的类 -- Ball :
定义一个监听器类 -- Listener:
再定义一个窗体类 -- frame :
最后定义一个类来调用main()方法,启动程序:
至此,一个弹球游戏就完成了,当然,还有好多需要改进的地方,比如添加一个背景动画,添加碰撞的声音啦,,,这些功能正在完善中,,欢迎广大朋友不吝赐教。
在此之前,只听说过“进程”,“程序”,但到底什么是“线程”?。。。。。。通过学习,明白了原来每一个程序都会包含有一个或若干个进程,而每一个进程其实是由一个或若干个线程组成。线程,是程序执行流的最小单元,每一个线程就是一个进程的实体,线程本身不拥有系统资源,与同属一个进程的其他线程共同的享有着进程所拥有的资源,线程之间的关系:一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。
在java.util下面有一个叫Thread的类和一个叫Runnable的接口,解决问题的方式有两种:一,创建一个类来继承Thread类,并重写run()方法,然后实例化这个类的一个对象,通过调用start()方法来启动线程;二,定义一个接口来实现Runnable,并实现其run()方法,将所定义的接口作为Thread的构造方法的参数,最后再创建Thread类的对象并调用start()方法来启动线程。显然,第一种方式操作比较简单,就以它为例吧。
介绍了理论知识,该从代码着手了。我的理解其实很简单,那就是将之前所要运行的指令放入run()方法中即可。下面简单介绍弹球游戏开发:
很显然,这个游戏的实现要用到线程,思路是:随机生成的小球按照运动轨迹运动(球的起始位置,颜色,尺寸,运动方向以及速度在给定的范围内均是任意的),当小球接触到窗体的边框,运动方向按照“反射定律”发生相应的改变,小球之间接触到一起的时候会按照物理的碰撞原则弹开。
定义一个继承Thread的类 -- Ball :
package 线程; import java.awt.Color; import java.awt.Graphics; import java.util.ArrayList; import java.util.Random; import javax.swing.JPanel; public class Ball extends Thread{ private Graphics g; private JPanel southPanel; private ArrayList<Ball> list; //小球的默认参数:起始位置,半径,水平速度,竖直速度以及颜色 private int x = 100; private int y = 100; private int r = 20; private int speedX = 5; private int speedY = 5; private Color color; private boolean tagIsPause = false; private boolean tagIsStop = true; //构造方法,参数有:画布,面板,保存小球对象的队列 public Ball(Graphics g, JPanel southPanel, ArrayList<Ball> list) { this.g = southPanel.getGraphics(); this.southPanel = southPanel; this.list = list; //实例化随机数对象 Random rd = new Random(); //随机半径 r = rd.nextInt(3) * 10 + 20; //随机位置 x = rd.nextInt(southPanel.getPreferredSize().width - 2*r) + r; y = rd.nextInt(southPanel.getPreferredSize().height - 2*r) + r; //随机水平速度大小 speedX = (rd.nextInt(3) + 2) * 3; //如果对随机数求余数为1,则方向向左,否则向右 if(rd.nextInt(10) % 2 == 0) speedX = - speedX; //随机竖直速度 speedY = (rd.nextInt(3) + 2) * 3; //如果对随机数求余数为1,则方向向上,否则向下 if(rd.nextInt(10) % 2 == 0) speedY = - speedY; //随机颜色参数 color = new Color(new Random().nextInt(256), new Random().nextInt(256), new Random().nextInt(256)); } //初始化参数的方法 public void initData() { x = 100; y = 100; r = 20; speedX = 5; speedY = 5; Color color; tagIsPause = false; tagIsStop = false; } //自定义一个休眠方法,其参数为休眠的时间(单位:毫秒) public void MyWait(int millis) { try { sleep(millis); } catch (InterruptedException e) { e.printStackTrace(); } } //重写run()方法 public void run() { while(tagIsStop) { //调用自定义的休眠方法,使线程休眠20毫秒,一来可以减慢小球的速度,二来可以使计算机休眠,大大减少cpu的使用率 MyWait(20); //实现暂停和开始 if(tagIsPause) { continue; } //擦拭小球上一次的位置 clear(); //判断小球下一步的路径 move(); //绘制小球 drawBall(x, y, r); } } //擦拭小球的方法 public void clear() { g.setColor(southPanel.getBackground()); g.fillOval(x, y, 2*r, 2*r); } //对小球下一步的动作进行处理的方法 public void move() { for(int i = 0, j = 0, ix = 0, jx = 0; i < Math.abs(speedX) || j < Math.abs(speedY); i ++, j ++, ix ++, jx ++) { //每改变一个单位的横坐标,就判断“自己”是否与别的小球发生碰撞 isHit(); if(ix < Math.abs(speedX)) { if(speedX > 0) x ++; else if(speedX < 0) x --; } //每改变一个单位的纵坐标,就判断“自己”是否与别的小球发生碰撞 isHit(); if(jx < Math.abs(speedY)) { if(speedY > 0) y ++; else if(speedY < 0) y --; } } //如果小球接触到窗体,则是其运动方向改变 if(x >= 800 - (r + 20) || x <= 10 + r) speedX = - speedX; if(y >= 600 - (r + 10) || y <= 38 + 32) speedY = - speedY; } //判断小球之间是否碰撞的方法 public void isHit() { //遍历所有的小球 for(int i = 0; i < list.size(); i ++) { //获得当前的小球 Ball ball = list.get(i); //如果是“自己”,则参数不变 if(ball.equals(this)) { this.x = ball.x; this.y = ball.y; this.r = ball.r; this.color = ball.color; this.speedX = ball.speedX; this.speedY = ball.speedY; } //如果不是“自己”,则判断是否发生碰撞 else //如果发生碰撞了 if(Math.abs(ball.x - this.x) * Math.abs(ball.x - this.x) + Math.abs(ball.y - this.y) * Math.abs(ball.y - this.y) <= (ball.r + this.r) * (ball.r + this.r)) { //碰撞之后,速度的改变符合两大物理定律:动量守恒定律和机械能守恒定律 ball.speedX = ((ball.r - this.r) * ball.speedX + 2 * this.r * this.speedX) / (ball.r + this.r); this.speedX = ((this.r - ball.r) * this.speedX + 2 * ball.r * ball.speedX) / (ball.r + this.r); ball.speedY = ((ball.r - this.r) * ball.speedY + 2 * this.r * this.speedY) / (ball.r + this.r); this.speedY = ((this.r - ball.r) * this.speedY + 2 * ball.r * ball.speedY) / (ball.r + this.r); } } } //绘制一个小球的方法 public void drawBall(int x, int y, int r) { g.setColor(color); g.fillOval(x, y, 2*r, 2*r); } //暂停的方法 public void pause() { tagIsPause = true; } //开始的方法 public void reStart() { tagIsPause = false; } //停止的方法 public void Stop() { tagIsStop = false; } }
定义一个监听器类 -- Listener:
package 线程; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import javax.swing.JPanel; public class Listener implements MouseListener, ActionListener{ private Graphics g; private JPanel southPanel; private Frame frame; private String cmd; //保存小球对象的队列 private ArrayList<Ball> list = new ArrayList<Ball>(); //构造方法:参数为:画布,面板,以及窗体 public Listener(Graphics g, JPanel southPanel, Frame frame) { this.g = g; this.southPanel = southPanel; this.frame = frame; } @Override //获取动作命令 public void actionPerformed(ActionEvent e) { cmd = e.getActionCommand(); } @Override public void mouseClicked(MouseEvent e) { //判断触发的按钮 if("add".equals(cmd)) { //实例化小球对象 Ball ball = new Ball(g, southPanel, list); //将小球队想添加到队列中 list.add(ball); //启动线程 ball.start(); } if("pause".equals(cmd)) { //遍历队列 for(int i = 0; i < list.size(); i ++) { //获得当前的小球对象 Ball ball = list.get(i); //调用暂停方法 //ball.suspend(); ball.pause(); } } if("restart".equals(cmd)) { //遍历队列 for(int i = 0; i < list.size(); i ++) { //获得当前的小球对象 Ball ball = list.get(i); //调用开始方法 //ball.resume(); ball.reStart(); } } if("stop".equals(cmd)) { //遍历队列 for(int i = 0; i < list.size(); i ++) { //获得当前的小球对象 Ball ball = list.get(i); //暂停小球的运动 ball.pause(); //终止线程 ball.Stop(); } //初始化窗体,即“清屏” frame.iniUI(); } } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } }
再定义一个窗体类 -- frame :
package 线程; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; @SuppressWarnings("serial") public class Frame extends JFrame{ private Graphics g ; public void iniUI() { this.setSize(820, 678); //this.setLocationRelativeTo(null); JPanel jp = new JPanel(); jp.setLayout(new BorderLayout()); JPanel northPanel = new JPanel(); JButton jb1 = new JButton("添加"); JButton jb2 = new JButton("暂停"); JButton jb3 = new JButton("开始"); JButton jb4 = new JButton("停止"); jb1.setActionCommand("add"); jb2.setActionCommand("pause"); jb3.setActionCommand("restart"); jb4.setActionCommand("stop"); northPanel.add(jb1); northPanel.add(jb2); northPanel.add(jb3); northPanel.add(jb4); northPanel.add(new JLabel("点击“停止”清屏")); northPanel.setBackground(Color.GRAY); jp.add(northPanel, BorderLayout.NORTH); JPanel southPanel = new JPanel(); southPanel.setPreferredSize(new Dimension(this.getWidth(), this.getHeight() -northPanel.getPreferredSize().height)); southPanel.setLayout(new FlowLayout()); southPanel.setBackground(new Color(255, 255, 255)); jp.add(southPanel, BorderLayout.SOUTH); this.add(jp); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setVisible(true); Listener l = new Listener(g, southPanel, this); jb1.addActionListener(l); jb2.addActionListener(l); jb3.addActionListener(l); jb4.addActionListener(l); jb1.addMouseListener(l); jb2.addMouseListener(l); jb3.addMouseListener(l); jb4.addMouseListener(l); } }
最后定义一个类来调用main()方法,启动程序:
package 线程; public class MianTest { public static void main(String[] args) { Frame fr = new Frame(); fr.iniUI(); } }
至此,一个弹球游戏就完成了,当然,还有好多需要改进的地方,比如添加一个背景动画,添加碰撞的声音啦,,,这些功能正在完善中,,欢迎广大朋友不吝赐教。
相关推荐
《JAVA多线程教学演示系统》是一篇深入探讨JAVA多线程编程的论文,它针对教育领域中的教学需求,提供了一种生动、直观的演示方式,帮助学生更好地理解和掌握多线程技术。这篇论文的核心内容可能包括以下几个方面: ...
超线程技术,又称Hyper-Threading(HT)技术,是Intel公司推出的一种创新的处理器技术,旨在提升处理器的多任务处理能力。这项技术允许单个物理核心模拟出两个逻辑核心,使得操作系统和应用程序能够同时执行更多的...
java多线程技术论文—毕业设计论文说明书.
Java多线程编程技术试议(论文),写论文的时候买的参考资料,与大家分享。
《USB多线程数据管理论文》探讨了在现代工业控制中如何通过USB技术实现高效的数据采集和处理。本文主要关注PDIUSBD12这款USB接口器件及其在多线程环境下的应用,以满足实时数据采集系统的需求。 首先,文章提出问题...
Win32多线程技术的采用允许程序在单个进程内创建多个线程,实现多任务处理,显著提高了程序的并发执行能力。论文中提出的基于事件驱动的三缓冲区多线程结构,旨在更有效地利用CPU资源,保证用户点播的视音频可以实时...
多线程下载是通过同时开启多个下载任务,将一个大文件分割成多个小部分,每个部分由不同的线程单独负责下载。这种技术的核心在于充分利用网络带宽,避免单一线程下载时可能出现的网络瓶颈。通过这种方式,下载速度...
Java多线程下载工具是一种利用Java编程语言实现的高效文件下载技术,它通过将大文件分割成多个小部分,同时启动多个线程进行并行下载,显著提高了下载速度。这篇论文详细探讨了如何设计和实现这样一个工具,同时包含...
线程可以理解为下载的通道,一个线程就是一个文件的下载通道,多线程也就是同时开起好几个下载通道.当服务器提供下载服务时,使用下载者是共享带宽的,在优先级相同的情况下,总服务器会...结 论 27 参考文献 28 致 谢 29
2. 线程安全:在多线程环境中,线程安全是一个重要概念,指的是一种状态,即当多个线程同时访问和修改同一数据时,程序能够保证数据的一致性、完整性和正确性。每个线程在处理数据时必须考虑到其他线程的状态,确保...
在分析Java 多线程特性的基础上, 探讨了Java 多线程的测试策略及测试方法, 提出Java 多线程测试由类测试、集成模块测试和系统测试三个层次组成, 并讨论了多线程的继承测试、同步测试以及效率测试。
在本篇论文“Linux下多线程编程的聊天软件”中,作者李杨探讨了如何利用Linux操作系统和多线程编程技术开发一款功能完备的网络聊天软件。在信息时代的背景下,网络聊天工具已经成为日常生活中不可或缺的通讯手段,而...
JavaScript,作为一种广泛应用于Web开发的脚本语言,一直以来都是单线程执行的。然而,在处理复杂的计算任务或者大型数据操作时,单线程的模式可能会导致浏览器变得卡顿,用户体验下降。为了解决这个问题,开发者们...
多线程下载技术是现代网络下载工具的核心特性之一,它通过将大文件分割成多个小部分并同时下载这些部分,显著提高了下载效率。这种技术在处理大文件,如高清视频、大型软件安装包或游戏客户端时尤为重要,因为它们...
在Java编程中,多线程是一项关键特性,它允许程序同时执行多个任务,极大地提高了效率。在本项目“Java多线程与线程安全实践-基于Http协议的断点续传”中,我们将深入探讨如何利用Java的多线程机制实现HTTP协议下的...