欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

线程的理解

程序员文章站 2022-03-13 23:27:02
...

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

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

        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);
	}

}

 效果图:
线程的理解
            
    
    博客分类: Java thread 
 

  • 线程的理解
            
    
    博客分类: Java thread 
  • 大小: 139 KB
相关标签: thread