简单地说,线程就是程序中独立的运行片段,一个程序就是一个进程,而一个进程里面一般不会只有一个线程,多数情况是多条路线同时执行。
之前写的东西,画板也好,五子棋也好,都是单线程的,就是说一个程序里面从头到尾都只有一个线程,即执行顺序,只能执行完上一句才能继续下一句。
但是现实生活中显然不是这样的,一种事物或现象的出现肯定是多个因素同时影响的结果,既然面向对象是模拟现实,自然一个程序的运行结果也要有几个不同线程来共同实现。
在Java中实现多线程的两种方法:
1、创建一个类去继承Thread类,重写Thread类中的run方法。
2、创建一个类实现Runnable 接口,实现接口中的run方法。在创建新的线程对象的时候,通过构造方法传入这个类的对象。
不管是哪种方法,线程所执行的操作都是run方法里面的内容。
我们要实现多线程需要的操作一般有三步:
1、定义线程中的run方法里的内容,即线程的执行语句。
2、建立用户线程实例。
3、启动线程,调用线程对象的start方法。
以下是用线程实现的弹球游戏。
package 线程; public interface Config { final static int SIZE = 50; final static int X = 20; final static int Y = 20; }
主线程:
package 线程; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.util.ArrayList; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class XianCheng { private JPanel jp2; private ArrayList<MyThread> list = new ArrayList(); public static void main(String[] args) { XianCheng xc = new XianCheng(); xc.initUI(); } public void initUI(){ //实例化窗体、面板、按钮... JFrame jf = new JFrame("线程-------------------"); JPanel jp1 = new JPanel(); jp2 = new JPanel(); JButton jb1 = new JButton("Start"); JButton jb2 = new JButton("Pause"); JButton jb3 = new JButton("Resume"); JButton jb4 = new JButton("Stop"); //设置窗体大小 jf.setSize(700,700); //设置关闭窗体时退出程序 jf.setDefaultCloseOperation(3); //设置窗体居中显示 jf.setLocationRelativeTo(null); //实例化监听器对象,直接传入窗体对象,而不是画布 MyListener l = new MyListener(jp2); //获取到队列 list = l.getList(); //添加监听器 jb1.addActionListener(l); jb2.addActionListener(l); jb3.addActionListener(l); jb4.addActionListener(l); //把按钮添加到面板上 jp1.add(jb1); jp1.add(jb2); jp1.add(jb3); jp1.add(jb4); //把面板添加到窗体上 jf.add(jp1,BorderLayout.NORTH); jf.add(jp2,BorderLayout.CENTER); //设置窗体可见 jf.setVisible(true); //获取面板上的画布对象 Graphics g = jp2.getGraphics(); //实例化图片对象 ImageIcon ima = new ImageIcon("Imas/bj.jpg"); //图片坐标 int x = 0; int y = 0; //图片移动速度 int yy = 0; int vy = 0; //图片移动加速度 int addvy = 1; while(true){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } //创建缓冲图片对象 BufferedImage buffer = new BufferedImage(jp2.getWidth(),jp2.getHeight(), BufferedImage.TYPE_INT_RGB); //获取到缓冲图片对象中的画布 Graphics g2 = buffer.getGraphics(); //将背景图画到缓冲图片上 g2.drawImage(ima.getImage(), 0, 0, null); //取出队列中的ball对象,调用画球的方法 for(int i =0; i<list.size() ;i++){ MyThread ball = list.get(i); ball.DrawBall(g2); } //这里画两张图的目的是在图片移动的时候两张图有衔接 g.drawImage(buffer, x, y, null); g.drawImage(buffer, x+buffer.getWidth(), y, null); x--; if(x+buffer.getWidth()<0){ x=0; } } } }
监听器:
package 线程; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import javax.swing.*; public class MyListener implements ActionListener{ private JPanel jp; private ArrayList<MyThread> list = new ArrayList(); //构造方法,传入要画图的面板 public MyListener(JPanel jp){ this.jp = jp; } //获取队列的方法 public ArrayList getList(){ return list; } //点击按钮的处理方法 public void actionPerformed(ActionEvent e) { //获取按钮的文本值 String s =e.getActionCommand(); //如果点击Start按钮 if(s.equals("Start")){ MyThread m1 = new MyThread(jp,list); m1.start(); list.add(m1); } //如果点击Pause按钮 if(s.equals("Pause")){ //循环遍历队列取出队列中的对象,设置暂停标志位为true for(int i = 0 ;i<list.size();i++){ MyThread m1 = list.get(i); m1.setPauseFlag(true); } } //如果点击Resume按钮 if(s.equals("Resume")){ //循环遍历队列取出队列中的对象,设置暂停标志位为false for(int i = 0 ;i<list.size();i++){ MyThread m1 = list.get(i); m1.setPauseFlag(false); } } //如果点击Stop按钮 if(s.equals("Stop")){ //把队列中的对象全部清空 while(!list.isEmpty()){ list.remove(0); } } }
画球的线程:
package 线程; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.util.ArrayList; import java.util.Random; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class MyThread extends Thread { private JPanel jp; private int X,Y,R;//坐标、半径 private int change_x,change_y;//速度 private Color color; private Graphics2D g; //暂停和停止的标志位 private boolean pauseFlag = false,stopFlag = false; //存放小球对象的队列 private ArrayList<MyThread> list; //记录小球撞击之前的坐标 private int oldx,oldy; public MyThread(JPanel jp,ArrayList<MyThread> list){ //属性初始化 this.jp = jp; this.list = list; Random r = new Random(); //给速度、半径和颜色随机赋值 change_x = r.nextInt(2)+1; change_y = r.nextInt(2)+1; R = r.nextInt(40)+20; color = new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)); X = R; Y = R; } public void run(){ //设置为一直循环 while(true){ //每次循环休眠5毫秒 try { Thread.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } //判断是否停止,如果停止了就返回 if(stopFlag){ return; } //判断是否暂停,如果暂停就不执行下面的代码 if(pauseFlag){ continue; } //调用改变坐标的方法 changeXY(); } } //判断坐标,改变速度 public void changeXY(){ //记录原来的坐标,小球撞击时不会粘在一起 oldx = X; oldy = Y; //先改变坐标 X+=change_x; Y+=change_y; //调用check方法,判断小球之间是否撞击 check(); //如果小球运动到边界则改变方向 if(X+R>jp.getWidth()){ change_x = -change_x; } if(X-R<0){ change_x = Math.abs(change_x); } if(Y+R>jp.getHeight()){ change_y = -change_y; } if(Y-R<0){ change_y = Math.abs(change_y); } } //暂停 public void setPauseFlag(boolean b){ pauseFlag = b; } //停止 public void setStopFlag(boolean b){ stopFlag = b; } //画球的方法 public void DrawBall(Graphics g){ int red = color.getRed(); int green = color.getGreen(); int bule = color.getBlue(); int xx = X; int yy = Y; int rr = R; //利用循环画出立体效果的圆 for(int i = 0 ;i<50;i++){ red+=4; green+=4; bule+=4; if(red>255) red=255; if(green>255) green=255; if(bule>255) bule=255; Color c= new Color(red,green,bule); g.setColor(c); g.fillOval(xx-rr,yy-rr, rr*2 ,rr*2); xx+=1; yy+=1; rr-=2; } } //判断小球之间是否碰撞 public boolean check(){ for(int i = 0;i<list.size();i++){ //利用循环取出队列中的对象 MyThread b = list.get(i); //如果是它本身就不需要判断 if(b == this) continue; //利用勾股定理 int x0 = b.X - this.X; int y0 = b.Y - this.Y; int r0 = b.R + this.R; //算出两球之间的距离 int distence = (int) Math.sqrt(x0*x0+y0*y0); //如果距离小于半径之和就代表相撞 if(distence < r0){ //互相交换水平速度 int temp_x = this.change_x; this.change_x = b.change_x; b.change_x = temp_x; //互相交换竖直速度 int temp_y = this.change_y; this.change_y = b.change_y; b.change_y = temp_y; X = oldx; Y = oldy; return true; } } return false; } }
相关推荐
本项目以"java多线程实现大批量数据导入源码"为题,旨在通过多线程策略将大量数据切分,并进行并行处理,以提高数据处理速度。 首先,我们需要理解Java中的线程机制。Java通过`Thread`类来创建和管理线程。每个线程...
总之,Java多线程和异步调用是构建高效、响应迅速的应用程序的关键技术。通过合理利用这些工具和机制,开发者可以编写出能够充分利用多核处理器优势的代码,从而提高软件性能。在实际应用中,理解并熟练掌握这些概念...
本主题将深入探讨如何在Java多线程环境下实现进度条功能。 首先,理解Java多线程的基本概念至关重要。Java通过Thread类和Runnable接口来支持多线程。创建一个新线程通常有两种方式:继承Thread类并重写run()方法,...
在Java编程语言中,实现多线程文件传输是一种优化程序性能、提高系统资源...在提供的`java多线程文件传输`压缩包中,可能包含了实现这些概念的示例代码,通过分析和学习,可以更好地理解多线程文件传输的原理和实践。
java多线程实现TCP连接UDP聊天的聊天程序
在Java编程中,多线程是一项关键特性,它允许程序同时执行多个任务,极大地提高了效率。本实例将探讨如何利用Java实现一个具有进度条显示功能的多线程应用。进度条通常用于可视化地表示某个任务的完成程度,这对于长...
java一些简单的多线程用法,适合初学者
总的来说,通过Java多线程和队列数据结构,我们可以有效地模拟排队叫号系统。这种模拟有助于理解和实践并发编程,同时也为我们解决实际问题提供了思路。在这个过程中,我们学习了线程同步、队列操作以及如何在Java中...
Java多线程是Java编程语言中一个非常重要的概念,它允许开发者在一个程序中创建多个执行线程并行运行,以提高程序的执行效率和响应速度。在Java中,线程的生命周期包含五个基本状态,分别是新建状态(New)、就绪...
2. **多线程实现**:Java提供了多种创建线程的方式,如继承`Thread`类或实现`Runnable`接口。在本例中,可能会选择实现`Runnable`接口,因为这样可以避免单继承的限制,增加代码的灵活性。 3. **同步机制**:在并发...
《JAVA多线程教学演示系统》是一篇深入探讨JAVA多线程编程的论文,它针对教育领域中的教学需求,提供了一种生动、直观的演示方式,帮助学生更好地理解和掌握多线程技术。这篇论文的核心内容可能包括以下几个方面: ...
Java多线程机制是Java编程中至关重要的一部分,它允许程序同时执行多个任务,提升应用程序的效率和响应性。以下是对各个知识点的详细说明: 9.1 Java中的线程: Java程序中的线程是在操作系统级别的线程基础上进行...
### 基于Java的多线程网络爬虫设计与实现 #### 概述 本文档探讨了在Java环境下设计与实现多线程网络爬虫的技术细节与实践方法。网络爬虫(Web Crawler),是一种自动抓取互联网上网页信息的程序或自动化脚本,其...
本资源主要探讨了如何在JAVA和C++中实现多线程,以及相关的测试和调试技术。 在JAVA中,多线程的实现主要依赖于`Thread`类和`Runnable`接口。开发者可以通过直接继承`Thread`类或实现`Runnable`接口来创建新的线程...
java实现多线程经典模型生产者消费java实现多线程经典模型生产者消费java实现多线程经典模型生产者消费java实现多线程经典模型生产者消费java实现多线程经典模型生产者消费java实现多线程经典模型生产者消费java实现...
Java多线程读大文件 java多线程写文件:多线程往队列中写入数据
在当今高度并发的应用环境中,Java多线程技术被广泛应用于处理数据库操作,以提升系统的响应速度和处理能力。本文将基于一个具体的Java多线程操作数据库的应用程序,深入探讨其背后的原理、实现细节以及潜在的挑战。...
### JAVA中的单线程与多线程概念解析 #### 单线程的理解 在Java编程环境中,单线程指的是程序执行过程中只有一个线程在运行。这意味着任何时刻只能执行一个任务,上一个任务完成后才会进行下一个任务。单线程模型...
综上所述,"java多线程查询数据库"是一个涉及多线程技术、线程池管理、并发控制、分页查询等多个方面的复杂问题。通过理解和掌握这些知识点,我们可以有效地提高数据库操作的效率和系统的响应速度。
Java多线程是Java编程中的一个重要概念,它允许程序同时执行多个任务,提高了程序的效率和响应速度。在Java中,实现多线程有两种主要方式:继承Thread类和实现Runnable接口。 1. 继承Thread类: 当我们创建一个新...