`

一个多线程的例子

    博客分类:
  • java
阅读更多

每一个任务称为一个线程,同时可以运行一个以上的程序称为多线程程序。

多线程与多进程本质的区别在于每个进程拥有自己的一套变量,而线程则共享数据。与进程相比,线程更轻量级,创建撤销一个线程比启动新进程容易的多。

以下程序中,当点击start后有一个小球开始在弹跳,但这个程序是一个单线程的,当球跳动时,点击close,程序不会结束,因为线程被球弹跳所占用,无法马上响应close。

Ball.java记录了运动的小球的坐标(x,y),并且有move方法将小球移动到下一个位置。

 

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import javax.swing.JPanel;

public class BallComponent extends JPanel {
	private ArrayList<Ball> balls=new ArrayList<Ball>();

	/*
	 * add a new ball to balls
	 */
	public void add(Ball b){
		balls.add(b);
	}
	
	/*
	 * paint the panel
	 */
	
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		Graphics2D g2=(Graphics2D)g;
		g2.setPaint(Color.RED);
		for(Ball b:balls){
			g2.fill(b.getShape());
		}
	}	
}

 

 

BallComponent.java继承了JPanel,用来画图。

 

 

import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;

public class Ball {
	
	private static final int XSIZE=15;
	private static final int YSIZE=15;
	private double x=0;
	private double y=0;
	private double dx=1;
	private double dy=1;
	
	/*
	 * change the value of x and y of the next position of ball 
	 */
	public void move(Rectangle2D bounds){
		x+=dx;
		y+=dy;
		if(x<bounds.getMinX()){
			x=bounds.getMinX();
			dx=-dx;
		}
		if(x+XSIZE>=bounds.getMaxX()){
			x=bounds.getMaxX()-XSIZE;
			dx=-dx;
		}
		if(y<bounds.getMinY()){
			y=bounds.getMinY();
			dy=-dy;
		}
		if(y+YSIZE>=bounds.getMaxY()){
			y=bounds.getMaxY()-YSIZE;
			dy=-dy;
		}
	}
	
	/*
	 * the shape of the ball at current position
	 */
	public Ellipse2D getShape(){
		return new Ellipse2D.Double(x,y,XSIZE,YSIZE);
	}

}

 

 BounceFrame.java完成整个界面,点击start按钮时调用addBall方法。

 

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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


public class BounceFrame extends JFrame {
	private static final int DEFAULT_WIDTH=450;
	private static final int DEFAULT_HEIGHT=350;
	private static final int STEPS=10000;
	private static final int DELAY=3;
	private BallComponent comp;
	
	public BounceFrame(){
	    setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);
	    comp = new BallComponent();
	    add(comp,BorderLayout.CENTER );
	    
	    JPanel buttonPanel=new JPanel();
	    addButton(buttonPanel,"Start",new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				addBall();
			}

	    });
	    addButton(buttonPanel,"Close",new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
	    });
	    add(buttonPanel,BorderLayout.SOUTH );
	}

	/*
	 * add button and listener to Container
	 */
	private void addButton(JPanel c, String title,
			ActionListener listener) {
		JButton button=new JButton(title);
		c.add(button);
		button.addActionListener(listener);
	}
	

	private void addBall() {
		try{
			Ball ball=new Ball();
			comp.add(ball);
			for(int i=0;i<STEPS;i++){
				ball.move(comp.getBounds());
				comp.paint(comp.getGraphics());//如果调用repaint,不会重画面板,因为addBall完全掌握这控制权
				Thread.sleep(DELAY);
			}
		}catch(InterruptedException e){
			
		}
	}
 
}
 

然后是程序的入口:

 

import java.awt.EventQueue;
import javax.swing.JFrame;

public class Bounce {
	public static void main(String[] arg){
		EventQueue.invokeLater(new Runnable(){
			public void run(){
				JFrame frame=new BounceFrame();
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				frame.setVisible(true);
			}
		});
	}
}

 

 要把这个程序改为多线程,要做如下改变:

如果将球移动的代码放在一个独立的线程中,这样每个球都在自己的线程中运行。由于每个线程都有机会得到运行,所以在在球弹跳期间用户点击close时,事件调度线程有机会关注到这一动作。

要想把弹跳球代码放在一个独立的线程中,只要实现Runnable接口,将动画代码放在run中。代码如下:

 

BallRunnable implements Runnable{
   ... ...
public void run() {
		try{
			for(int i=0;i<STEPS;i++){
				ball.move(comp.getBounds());
				comp.repaint();
				Thread.sleep(DELAY);
			}
		}catch(InterruptedException e){
			
		}
	}
   ... ...
}

 

 当点击start后启动一个新线程:

 

Ball ball=new Ball();
comp.add(ball);
Runnable r=new BallRunnable(ball,comp);
Thread t=new Thread(r);
t.start();
 

也可以继承Thread类来定义一个线程,然后再点击start后构造一个子类对象,启动线程。这种方法已经不再推荐,要为每一个任务创建独立的线程付出的代价太大。

 

import java.awt.Component;

public class BallRunnable implements Runnable{
	private Ball ball;
	private Component comp;
	private static final int STEPS=100000;
	private static final int DELAY=3;
	
	public BallRunnable(Ball ball,Component comp){
		this.ball=ball;
		this.comp=comp;
	}

	public void run() {
		try{
			for(int i=0;i<STEPS;i++){
				ball.move(comp.getBounds());
				comp.repaint();
				Thread.sleep(DELAY);
			}
		}catch(InterruptedException e){
			
		}
	}
}

 

 改进后的BounceFrame.java

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class BounceFrame extends JFrame{
	private static final int DEFAULT_WIDTH=450;
	private static final int DEFAULT_HEIGHT=350;
	private BallComponent comp;
	
	public BounceFrame(){
	    setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);
	    comp = new BallComponent();
	    add(comp,BorderLayout.CENTER );
	    
	    JPanel buttonPanel=new JPanel();
	    addButton(buttonPanel,"Start",new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				addBall();
			}

	    });
	    addButton(buttonPanel,"Close",new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
	    });
	    add(buttonPanel,BorderLayout.SOUTH );
	}

	/*
	 * add button and listener to Container
	 */
	private void addButton(JPanel c, String title,
			ActionListener listener) {
		JButton button=new JButton(title);
		c.add(button);
		button.addActionListener(listener);
	}
	

	private void addBall() {
			Ball ball=new Ball();
			comp.add(ball);
			Runnable r=new BallRunnable(ball,comp);
			Thread t=new Thread(r);
			t.start();
		}
}
 
分享到:
评论

相关推荐

    今天没事给大家写一个多线程例子

    今天没事给大家写一个多线程例子 今天没事给大家写一个多线程例子

    易语言大漠多线程例子.rar

    这个"易语言大漠多线程例子.rar"压缩包包含了一个使用大漠插件实现多线程编程的示例项目。 多线程是现代程序设计中一个关键的概念,它允许程序同时执行多个任务,提高了程序的效率和响应性。在易语言中,使用大漠...

    多线程例子 演示多线程使用

    在计算机编程中,多线程是一种...这个“多线程例子.cpp”文件很可能是实现上述概念的一个具体实例,可能包括线程创建、同步、通信等操作。通过分析和学习这个例子,你可以更好地理解如何在实际项目中运用多线程技术。

    易语言多线程简单实用例子分享

    多线程是现代软件开发中的一个重要概念,它允许程序同时执行多个任务,而不是顺序地执行。在易语言中,通过创建和管理多个线程,我们可以实现后台计算、异步操作以及用户界面的流畅交互。这种方式尤其适合于处理大...

    Delphi API 串口通信 多线程例子.rar

    在"Delphi API 串口通信 多线程例子.rar"这个压缩包中,可能包含了一个示例项目,展示了如何使用Delphi的API和多线程技术实现串口通信。文件名"codefans.net"可能指的是一个代码分享网站,或者是一个特定的源代码...

    5个qt多线程例子

    第一个例子“调试---1.tar.gz”可能是一个用于调试多线程应用程序的工具,帮助开发者跟踪线程间的交互和同步问题。调试多线程程序是一项挑战,因为它涉及到线程间的复杂关系和同步原语,如信号和槽、mutexes、...

    易语言借助乐玩图色脚本多线程例子

    在这个“易语言借助乐玩图色脚本多线程例子”中,我们将探讨如何利用易语言结合特定的第三方库,如“乐玩”和“鱼刺”,实现多线程编程。 乐玩图色脚本可能是指一个图形界面工具或库,它为易语言提供了丰富的图形...

    c++多线程编程的十个例子

    在多线程环境中,异常处理变得复杂,因为一个线程抛出的异常可能会影响到其他线程。理解如何在多线程程序中正确地处理异常是至关重要的。 通过学习和实践这些例子,你将能够熟练掌握C++多线程编程的核心概念,并...

    鱼刺多线程注册源码例子(鱼刺多线程稳定框架)

    "鱼刺多线程注册源码例子"是一个基于"鱼刺多线程稳定框架"的编程实践,旨在展示如何在软件开发中有效地利用多线程技术来提高程序的执行效率和稳定性。在这个例子中,"鱼刺框架"可能是一个专门为多线程编程设计的开源...

    C语言使用多线程例子

    在这个“C语言使用多线程例子”中,我们将探讨如何使用Windows API中的`CreateThread`函数来创建线程。 首先,`CreateThread`函数是Windows操作系统提供的一种API调用,用于在进程中创建新的执行线程。它的基本语法...

    一个C++多线程例子

    多线程例子.cpp,有兴趣的可以下来研究一下.....

    多线程例子

    标题“多线程例子”表明这是一个关于如何在程序中实现并使用多线程的实例。多线程通常用于处理并发操作,如在用户界面(UI)中,可以同时进行数据加载、用户交互和其他后台任务。 描述中提到的例子将Windows窗口...

    vb.net多线程例子

    总的来说,VB.NET的多线程功能强大且易于使用,对于初学者来说,通过简单的例子学习多线程是一个很好的起点。不过,随着项目复杂性的增加,理解并掌握线程管理、同步和通信机制至关重要,这将有助于编写出更加健壮和...

    java多线程例子

    Java 多线程例子 Java 多线程是 Java 编程语言中的一种基本概念,它允许程序同时执行多个任务,从而提高程序的性能和效率。本文将通过三个实用的例子,讲解 Java 多线程的基本概念和使用方法。 第一个例子:创建多...

    java多线程的一个简单例子

    很简单的一个java多线程例子,希望多大家有帮助

    udp多线程例子

    【标题】"udp多线程例子"涉及到的是在Linux环境下使用UDP协议进行多线程编程的知识点。UDP(User Datagram Protocol)是一种无连接的、不可靠的传输层协议,常用于需要快速传输数据且对数据完整性要求不高的场景。多...

    易语言多线程操作例子

    一个易语言操作多线程的例子,分享一下,对于多线程操作,我还是觉得C++更好一点!

    多线程 串口的多线程例子

    标题中的“多线程 串口的多线程例子”是指在编程中处理串行通信时采用多线程技术的一个示例。串口通信是一种在计算机及其外设间通过串行数据传输的方式进行通信的技术,通常用于设备间的短距离通信。多线程则是在...

    Arduino 使用多线程例子

    标题中的“Arduino 使用多线程例子”意味着我们将探讨如何在Arduino平台上实现多任务并行处理。通常,Arduino基于单片机,不直接支持操作系统或内置的多线程机制。但是,通过巧妙编程和使用库,我们可以模拟多线程的...

    易语言完美多线程控制例子

    总的来说,“易语言完美多线程控制例子”是一个极好的学习资源,它让我们有机会实践易语言的多线程编程,掌握如何在实际项目中应用这些技术。无论是对于初学者还是经验丰富的开发者,理解并掌握多线程控制都是提升...

Global site tag (gtag.js) - Google Analytics