`
空城旧梦why
  • 浏览: 25373 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

线程的理解

    博客分类:
  • Java
阅读更多

        对于每个学过计算机的一些基础知识的都应该知道,线程和进程。关于这两个我是这么区别的,从包含关系来说,一个进程可以包含多个线程,进程是系统分配资源的基本单位,多个线程之间的资源是共享的,而多个进程之间的资源不是共享的。

        而在软件的开发中使用线程可以提高软件的性能。

        Java中线程的使用有两中方式:

                1、public MyThread extends Thread{

                             public void run() {

                                 // 自己的代码

                             }

                         }

                         MyThread t = new MyThread(); // 实例化一个MyThread对象

                         t.start(); // 启动线程

                   2、public class MyThread implements Runnable {

                             public void run() {

                                 // 自己的代码

                             }

                         }

                         Thread t = new Thread(new MyThread()); // 利用Mythread类的对象创建一个Thread对象

                         t.start(); // 启动线程

下面是我写的一个线程游戏,里面用了一个线程来绘制小球

 

主界面的类

 

package com.why.frame;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

import com.why.thread.Ball;

public class GameFrame extends JFrame implements ActionListener, Runnable {

	private static final long serialVersionUID = 1L;
	private JPanel show_panel;
	private Graphics2D g;
	private ArrayList<Ball> list = new ArrayList<Ball>();
	private ArrayList<Ball> addList = new ArrayList<Ball>();
	private boolean pauseFlag = false;
	private boolean stopFlag = false;
	private int width;
	private int height;

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		GameFrame f = new GameFrame();
		f.initUI();
		new Thread(f).start();
	}

	public void initUI() {
		this.setSize(new Dimension(800, 600));
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLocationRelativeTo(null);
		this.setTitle("线程小游戏");

		JPanel button_panel = new JPanel(new FlowLayout());
		button_panel.setBackground(Color.DARK_GRAY);

		JButton addButton = new JButton("Add");
		addButton.addActionListener(this);
		button_panel.add(addButton);

		JButton pauseButton = new JButton("Pause");
		pauseButton.addActionListener(this);
		button_panel.add(pauseButton);

		JButton resumeButton = new JButton("Resume");
		resumeButton.addActionListener(this);
		button_panel.add(resumeButton);

		JButton stopButton = new JButton("Stop");
		stopButton.addActionListener(this);
		button_panel.add(stopButton);
		this.add(button_panel, BorderLayout.NORTH);

		show_panel = new JPanel();
		this.add(show_panel, BorderLayout.CENTER);
		this.setVisible(true);
		width = show_panel.getWidth();
		height = show_panel.getHeight();
	}

	/**
	 * 响应按钮被按下的事件
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		String command = e.getActionCommand();
		switch (command) {
		case "Add":// 当按下添加按钮时执行的动作
			if (!pauseFlag) {
				stopFlag = false;
				Ball ball = new Ball();
				// 将添加的小球暂时添加到addList列表中
				addList.add(ball);
			}
			break;
		case "Pause":// 当按下暂停按钮时执行的动作
			pauseFlag = true;
			break;
		case "Resume":// 当按下继续按钮时执行的动作
			pauseFlag = false;
			break;
		case "Stop":// 当按下停止按钮时执行的动作
			stopFlag = true;
			break;
		default:
			break;
		}
	}

	/**
	 * 绘制小球
	 */
	@Override
	public void run() {
		// TODO Auto-generated method stub
		//--------------------------利用双缓冲不让界面闪烁---------------------
		// 创建一个缓冲图片
		BufferedImage image = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);
		// 取得缓冲图片上的画笔对象
		Graphics2D g2d = (Graphics2D) image.getGraphics();
		//--------------------------------------------------------------------

		// 消除绘图锯齿
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		this.g = (Graphics2D) show_panel.getGraphics();
		while (true) {
			// 取得显示小球的面板上的画笔对象
			if (show_panel.getWidth() != width
					|| show_panel.getHeight() != height) {
				width = show_panel.getWidth();
				height = show_panel.getHeight();
				image = new BufferedImage(width, height,
						BufferedImage.TYPE_INT_RGB);
				g2d = (Graphics2D) image.getGraphics();
				this.g = (Graphics2D) show_panel.getGraphics();
				g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
						RenderingHints.VALUE_ANTIALIAS_ON);
			}
			g2d.clearRect(0, 0, image.getWidth(), image.getHeight());
			System.gc();
			// 绘制小球
			for (Ball ball : list) {
				if (!pauseFlag)
					ball.move(show_panel, list);
				if (!stopFlag)
					ball.drawBall(g2d);
			}
			// 将addList中的小球添加到保存小球的列表中
			if (!addList.isEmpty()) {
				list.addAll(addList);
				addList.clear();
			}
			// 如果按下停止按钮清除小球
			if (stopFlag) {
				list.clear();
			}
			// 将缓冲图片画到显示小球的面板上
			g.drawImage(image, 0, 0, null);
			try {
				Thread.sleep(15);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

 小球类:

 

package com.why.thread;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JPanel;

public class Ball {

	private Color color;
	private double x, y;
	private double vx;
	private double vy;
	private int radius;
	private Ellipse2D.Double shape;

	public Ball() {
		Random random = new Random();
		this.color = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
		this.vx = random.nextInt(5) + 3;
		this.vy = random.nextInt(5) + 3;
		this.x = 0;
		this.y = 0;
		this.radius = random.nextInt(30) + 20;
		this.shape = new Ellipse2D.Double(x, y, radius << 1, radius << 1);
	}

	/**
	 * 绘制小球的方法
	 */
	public void drawBall(Graphics2D g) {
		g.setColor(color);
		g.fill(shape);
	}

	/**
	 * 移动小球位置的方法
	 */
	public void move(JPanel panel, ArrayList<Ball> list) {
		x += vx;
		y += vy;
		Rectangle rect = panel.getBounds();
		if (x < 0) {
			x = 0;
			vx = Math.abs(vx);
		}
		if (x > rect.getWidth() - radius * 2) {
			x = rect.getWidth() - radius * 2;
			vx = -Math.abs(vx);
		}
		if (y < 0) {
			y = 0;
			vy = Math.abs(vy);
		}
		if (y > rect.getHeight() - radius * 2) {
			y = rect.getHeight() - radius * 2;
			vy = -Math.abs(vy);
		}
		check(list); // 调用碰撞处理方法
		shape.setFrame(x, y, radius << 1, radius << 1);
	}

	/**
	 * 对小球进行碰撞检测,以及如果发生碰撞将其反弹的方法
	 */
	private void check(ArrayList<Ball> list) {
		for (int i = 0; i < list.size(); i++) {	// 判断小球间是否发生碰撞
			Ball ball = list.get(i);
			if (ball == this)	// 自己和自己不碰撞
				continue;
			if (checkCollision(ball)) { // 当两球间的距离小于直径时,可认为两小球发生了碰撞
				rebound(ball);
				ball.rebound(this);
			}
		}
	}

	private void rebound(Ball ball) {
		double degree = Math.atan((y + radius - ball.y - ball.radius) / (x + radius - ball.x - ball.radius));//获取自己与发生碰撞的小球之间所形成的夹角,因为夹角只能在-pi/2-pi/2之间,所以还需判断两球的x坐标之间的关系
		double v = Math.sqrt(vx * vx + vy * vy);
		if (x + radius > ball.x + ball.radius) { // 如果自己的x坐标大于发生碰撞的小球的x坐标,由数学知识可知自己应该往正向运动
			vx = Math.cos(degree) * v;
			vy = Math.sin(degree) * v;
		} else { // 如果自己的x坐标小于发生碰撞的小球的x坐标,由数学知识可知应该朝负向运动
			vx = -Math.cos(degree) * v;
			vy = -Math.sin(degree) * v;
		}
	}

	/**
	 * 检测是否发生碰撞
	 * @param ball 要被检测的小球
	 * @return 如果碰撞发生返回true,否则返回false
	 */
	private boolean checkCollision(Ball ball) {
		double lenx = x + radius - ball.x - ball.radius;
		double leny = y + radius - ball.y - ball.radius;
		double len = radius + ball.radius;
		return Math.pow(lenx, 2) + Math.pow(leny, 2) <= Math.pow(len, 2);
	}

}

 效果图:

 

  • 大小: 139 KB
分享到:
评论

相关推荐

    IOS多线程理解

    iOS多线程是移动应用开发中不可或缺的技术,它允许程序在后台执行耗时任务,同时保持主线程的流畅,从而提供良好的用户体验。本文将深入探讨iOS的三种主要多线程编程方式:NSThread、NSOperation和NSOperationQueue...

    java线程理解小程序

    这就是"java线程理解小程序"的初衷,帮助开发者学习如何在Android环境中正确地管理和使用线程。 首先,我们需要理解Java中的线程创建方式。最基础的是通过实现`Runnable`接口或继承`Thread`类来创建线程。实现`...

    线程的理解,看完就明白了

    ### 线程的理解,看完就明白了 在计算机科学领域,**线程**是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。一个进程(Process)至少有一个线程,如果一个进程中只有一个线程...

    C#多线程操作技术

    理解线程的概念 理解.NET中线程的属性和方法 创建和使用线程 理解线程的特点、优点及使用场合 在.NET程序设计中,线程是使用Thread类(或Timer类(线程计数器)、ThreadPool类(线程池))来处理的,这些类在System....

    vc下创建子线程例子

    以下是对VC下创建子线程例子的深入解析,旨在帮助初学者克服对线程理解的难点。 ### 线程基本概念 在计算机科学中,线程是程序执行流的最小单元,一个标准的程序由多个线程组成。线程允许程序在同一时间处理多个...

    进程与线程的生动形象理解

    ### 进程与线程的生动形象理解 #### 一、引言 进程与线程作为操作系统中的核心概念,对于理解和开发高效的软件至关重要。本文旨在通过一个生动的类比来帮助读者更好地理解进程与线程的基本概念及其差异,并进一步...

    C#语言多线程初步理解

    本教程将帮助初学者理解C#中的多线程概念,并通过一个Windows Forms应用程序实例,演示如何在WinForm控件中启动、暂停、继续子线程以及输出数据。 首先,我们来看多线程的基本概念。在单线程程序中,所有的任务按...

    多线程最完整的思维导图

    此外,线程的状态转换也是多线程理解的重要部分。从新建到运行,再到阻塞、等待、终止,线程经历了多个状态,了解这些状态有助于调试和优化多线程程序。 最后,线程安全的集合类是多线程编程中必不可少的工具。例如...

    关于线程的小程序

    本文将深入探讨“关于线程的小程序”所涵盖的知识点,旨在为初学者提供一个全面的线程理解和实践基础。 一、线程的概念 线程是操作系统分配CPU时间片的基本单位,它在进程中执行,每个进程可以有多个线程。线程之间...

    多线程thread线程的理解

    在学习多线程时,我们需要理解以下几个核心概念: 1. **线程的创建**:程序可以通过创建`Thread`对象并调用其`start()`方法来启动一个新线程。在Java中,还可以通过实现`Runnable`接口或继承`Thread`类来创建线程。...

    理解多线程,写一个多线程应用程序,要求能在用户级实现线程的调度,如启动、挂起、恢复、停止,的C thread、java thread实现。

    总结起来,无论是C语言还是Java,实现多线程都需要理解线程的创建、调度、同步和通信。通过合理利用线程,开发者可以编写出更高效、响应更快的应用程序,充分利用现代计算机的多核优势。在实际开发中,应根据需求...

    Swing线程的深入理解和SwingWorker基础知识介绍

    Swing线程的深入理解和SwingWorker基础知识介绍 Swing线程是Java程序设计中的一种重要概念,用于处理图形用户界面(GUI)中的线程问题。在本文中,我们将深入探讨Swing线程的理解和SwingWorker基础知识,并通过实例...

    MFC多线程 工作者线程 用户界面线程

    在Windows编程领域,MFC(Microsoft Foundation Classes)是微软提供的一套C++库,用于简化Windows应用程序的...开发者需要理解线程间通信、线程安全和调试技巧,才能充分发挥多线程的优势,创建出健壮的MFC应用程序。

    易语言多线程许可证的理解使用

    在易语言中,理解和使用多线程许可证可以帮助开发者更好地管理这些线程,防止因资源竞争导致的问题,如数据不一致性和死锁。 许可证系统是多线程编程中的一个工具,用于限制同时访问特定资源的线程数量。在易语言中...

    多线程之间的线程通信

    例如,在服务器-客户端模型中,通过套接字进行通信,线程可以在同一进程中模拟网络通信,从而更好地理解线程通信的问题。 5. **消息队列(Message Queue)**:线程可以通过发送和接收消息来进行通信,消息队列负责...

    单线程与多线程的区别

    理解这两种模型是编程尤其是服务器端开发的基础,尤其是在Java、C#等支持多线程的编程语言中。 首先,让我们来详细探讨一下**单线程**的概念。在单线程环境中,程序的执行是由一个单一的执行线程控制的,这意味着...

    多线程列子多线程列子多线程列子

    在IT领域,多线程是程序设计中的一个重要概念,尤其在现代计算机系统中,它能够充分利用多核处理器的计算能力,提高程序的执行效率。...理解并掌握多线程编程,能帮助开发者编写出更高效、稳定的软件系统。

Global site tag (gtag.js) - Google Analytics