`
泽在1993
  • 浏览: 5881 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

小论线程

 
阅读更多
      最初听闻“线程”这个词,是在那时候自己写的小程序存在着这样的诟病:触发按钮之后,监听器捕捉到用户操作,在其触发动作所执行的指令尚未结束前,按钮是会一直“凹下去”的,待到所有的指令运行结束之后,才会“弹起来”,只个时候才能再次点击按钮。听闻学习了线程之后就能解决这个问题。带着这样的好奇,走进了线程的学习。。。

    在此之前,只听说过“进程”,“程序”,但到底什么是“线程”?。。。。。。通过学习,明白了原来每一个程序都会包含有一个或若干个进程,而每一个进程其实是由一个或若干个线程组成。线程,是程序执行流的最小单元,每一个线程就是一个进程的实体,线程本身不拥有系统资源,与同属一个进程的其他线程共同的享有着进程所拥有的资源,线程之间的关系:一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。
   
    在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();
	}
}


    至此,一个弹球游戏就完成了,当然,还有好多需要改进的地方,比如添加一个背景动画,添加碰撞的声音啦,,,这些功能正在完善中,,欢迎广大朋友不吝赐教。
分享到:
评论
1 楼 ayaome 2014-03-21  

相关推荐

    JAVAJAVA多线程教学演示系统论文

    《JAVA多线程教学演示系统》是一篇深入探讨JAVA多线程编程的论文,它针对教育领域中的教学需求,提供了一种生动、直观的演示方式,帮助学生更好地理解和掌握多线程技术。这篇论文的核心内容可能包括以下几个方面: ...

    超线程技术方面的论文集

    超线程技术,又称Hyper-Threading(HT)技术,是Intel公司推出的一种创新的处理器技术,旨在提升处理器的多任务处理能力。这项技术允许单个物理核心模拟出两个逻辑核心,使得操作系统和应用程序能够同时执行更多的...

    USB多线程数据管理论文.doc

    此外,本论文还提出了一系列优化措施,例如线程优先级的合理分配、线程同步与通信机制的优化,以及线程异常处理策略,这些都是保障多线程程序稳定运行、发挥最大效率的关键。 最后,本文总结了USB技术结合多线程...

    java多线程技术论文

    java多线程技术论文—毕业设计论文说明书.

    Java多线程编程技术试议(论文)

    Java多线程编程技术试议(论文),写论文的时候买的参考资料,与大家分享。

    论文研究-多线程技术在条件接收系统中的应用 .pdf

    Win32多线程技术的采用允许程序在单个进程内创建多个线程,实现多任务处理,显著提高了程序的并发执行能力。论文中提出的基于事件驱动的三缓冲区多线程结构,旨在更有效地利用CPU资源,保证用户点播的视音频可以实时...

    多线程网络下载论文

    多线程下载是通过同时开启多个下载任务,将一个大文件分割成多个小部分,每个部分由不同的线程单独负责下载。这种技术的核心在于充分利用网络带宽,避免单一线程下载时可能出现的网络瓶颈。通过这种方式,下载速度...

    java多线程下载工具 论文

    Java多线程下载工具是一种利用Java编程语言实现的高效文件下载技术,它通过将大文件分割成多个小部分,同时启动多个线程进行并行下载,显著提高了下载速度。这篇论文详细探讨了如何设计和实现这样一个工具,同时包含...

    多线程下载技术论文.rar

    线程可以理解为下载的通道,一个线程就是一个文件的下载通道,多线程也就是同时开起好几个下载通道.当服务器提供下载服务时,使用下载者是共享带宽的,在优先级相同的情况下,总服务器会...结 论 27 参考文献 28 致 谢 29

    Java多线程与线程安全实践-基于Http协议的断点续传论文.pdf

    2. 线程安全:在多线程环境中,线程安全是一个重要概念,指的是一种状态,即当多个线程同时访问和修改同一数据时,程序能够保证数据的一致性、完整性和正确性。每个线程在处理数据时必须考虑到其他线程的状态,确保...

    论文研究-Java多线程测试策略及测试方法探讨.pdf

    在分析Java 多线程特性的基础上, 探讨了Java 多线程的测试策略及测试方法, 提出Java 多线程测试由类测试、集成模块测试和系统测试三个层次组成, 并讨论了多线程的继承测试、同步测试以及效率测试。

    linux多线程编程的聊天软件 (论文)

    在本篇论文“Linux下多线程编程的聊天软件”中,作者李杨探讨了如何利用Linux操作系统和多线程编程技术开发一款功能完备的网络聊天软件。在信息时代的背景下,网络聊天工具已经成为日常生活中不可或缺的通讯手段,而...

    javascript模拟多线程

    JavaScript,作为一种广泛应用于Web开发的脚本语言,一直以来都是单线程执行的。然而,在处理复杂的计算任务或者大型数据操作时,单线程的模式可能会导致浏览器变得卡顿,用户体验下降。为了解决这个问题,开发者们...

    多线程下载技术论文.pdf

    多线程下载技术是现代网络下载工具的核心特性之一,它通过将大文件分割成多个小部分并同时下载这些部分,显著提高了下载效率。这种技术在处理大文件,如高清视频、大型软件安装包或游戏客户端时尤为重要,因为它们...

    Java多线程与线程安全实践-基于Http协议的断点续传

    在Java编程中,多线程是一项关键特性,它允许程序同时执行多个任务,极大地提高了效率。在本项目“Java多线程与线程安全实践-基于Http协议的断点续传”中,我们将深入探讨如何利用Java的多线程机制实现HTTP协议下的...

Global site tag (gtag.js) - Google Analytics