`
文昌平蓝杰
  • 浏览: 56239 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

如何使用线程

阅读更多

线程:

 

   1.概念:线程就是一个独立的运行单位,其内部数据和状态都是完全独立的。简单的说,就是一旦触发,就由它自己去运行,不用再管,由系统自行去根据代码执行,所以一旦运行就马上返回,不用等待。这样可以实现多个线程同时执行。

   2.实现线程的3种方式:

1.继承Thread类实现线程

public class Bullet extends Thread{
			// 运动的速度
			private static int speed = 2;
			// 传入画布
			private Graphics g;
			// 当前子弹的名字
			String name;
			// 传入坦克的坐标值
			int x;
			int y;

			//调用启动函数
			public void run() {
			shot();
			}
			public void shot{
				"这里写入子弹运动的过程"
			}
		}
 

这里实现了一个子弹的运行过程,只要在shot方法中画出子弹运动的过程就可以了。这样其实就实现了一个简单的线程,当我们直接调用bullet的strat方法就可以了,如

Bullet bullet = new Bullet();
 		bullet.strat();
 

这里调用的是strat方法,可是由于这是一个线程对象,所以系统自动调用run()方法的东西,并立即返回。

这里问题就来了,我们为什么非要调strat去启动run方法呢,为什么不直接调用shot方法呢?呵呵,其实可以去试一试的,因为我们当时是设计有坦克的,这只是其中的子弹类而已,如果直接调用shot方法的话,需要等待,也就是说,在第一颗子弹结束之前,坦克是不能动的,并且不能发射第二颗子弹,明白了吗。这就是线程的作用,可以并行。在子弹运行的同时,坦克也可以运行,这才是符合逻辑。子弹作为一个单独的线程去运行。

注意:一定要记得重写run()方法。

2.实现Runnable的方法实现线程

1.前面写了很多来告诉为什么要使用线程,有什么好处,并且也说了通过继承的方法实现线程启动,这里介绍另一种常用方法,通过继承Runnable的方法实现线程的启动。还是以子弹作为研究对象,如:

public class BulletRunnable implement Runnable {
			//传入的坦克对象
			Tank tank;
			//重写构造方法
			public BulletRunnable(Tank tank, Graphics g) {
				this.g = g;
				this.tank = tank;
			}
			//调用启动函数
			public void run() {
				shot();
			}
			public void shot(){
				"这里画出子弹运动的过程"
			}
		}
 

这里创建了一个类,该类实现了Runnable接口,所以就必须实现它的抽象方法run(),其实前面的Thread也是实现的Runnable接口的,所以可以通过继承Thread类来实现线程的启动,现在我们自己写了一个类实现了Runnable,所以也可以通过这个类来启动线程。

所以只需要通过我们实现了接口的类创建一个线程,并调用线程即可。如:

BulletRunnable tr = new BulletRunnable(tank, g);
		Thread thread = new Thread(tr);
		// 线程启动
		thread.start();
 

这样一样可以启动线程。

3.通过匿名内部类,实现接口Runnable

      

 /**
	 	* 启动一个线程
	 	*/
		public void stratBullet(){
			//通过匿名内部类实现接口
			Runnable rab = new Runnable(){
				public void run(){
					“画出子弹运行的过程”
				}	
			}
			//启动线程
			Thread thread = new Thread(rab);
			thread.strat();	
		}
 

这样也实现了一颗子弹的发射,由于篇幅缘故,没有写出具体画出子弹的方法,因为这是个很复杂的问题,要考虑的诸如碰到坦克和墙等等的情况,所以代码非常复杂,没有把具体情况写出来。

   3.sleep方法的运用。

1.其实sleep方法的运用是比较重要的,因为一个线程在执行时,会一直占用资源,这是不合理的,因为一般情况下,比如一个坦克,在它未被消灭之前,会一直执行run方法,因此,在它在打死之前,其实一直都在调用run方法。如果不去处理这种情况,那么系统的cpu占用会达到100%,这是绝对不合理的,就像程序陷入死循环一样的效果。所以我们需要调用Thread的sleep方法。它可以让程序休眠一段时间,之后继续运行。

2.写出一段子弹类的,shot方法具体代码;

while (true) {// 开始发射子弹
			// 先画一个子弹
			g.drawImage(image, x, y, WideB, HighB, null);
			try {
				this.sleep(10);// 线程休眠
				g.setColor(Color.BLACK);
				g.fillRect(x, y, WideB, HighB);// 画矩形把原先图片盖住

				// 判断坦克方向,改变相应运动坐标
				if (direction.equals("Right")) {
					x += speed;
				}
				if (direction.equals("Left")) {
					x -= speed;
				}
				if (direction.equals("Up")) {
					y -= speed;
				}
				if (direction.equals("Down")) {
					y += speed;
				}
				// 画出新位置,走下一步
				g.drawImage(image, x, y, WideB, HighB, null);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			// 判断是否到边界,是跳出循环
			if (x > 885 || x < -5|| y > 580|| y < -5) {
				tank.countBomb++;
				System.out.println(tank.countBomb);
				break;
			}
		}
 

可以看出,其实在子弹出去边界之前,一直是在以死循环的方式不断执行,如果不让程序休眠的话,就会非常快的执行完成,我们根本看不到子弹飞出的效果,也就是说子弹的运行速度是由子弹的休眠时间和速度一起影响的。只是子弹而已所以影响不太大,试想一下,如果一个坦克没有休眠时间是多么难看堪的事情,所以休眠,对于线程来说,是很重要的。

休眠时间以毫秒计算,如果参数是1000,则会休眠一秒。

分享到:
评论

相关推荐

    C++ 如何正确的使用线程 释放线程资源

    本文将详细讨论如何在C++中正确使用线程以及如何释放线程资源,并重点阐述joinable状态和detached状态的线程处理方式。 首先,我们需要了解线程的两种基本状态:joinable状态和detached状态。 1. **Joinable状态**...

    j2ee中使用线程的小DEMO

    以下是对"j2EE中使用线程的小DEMO"的详细解释。 在J2EE应用中,线程的使用主要有以下几个方面: 1. **Web容器中的线程**:当一个HTTP请求到达服务器时,Web容器(如Tomcat、Jetty等)会自动创建一个新的线程来处理...

    WPF 使用线程更新UI

    标题“WPF 使用线程更新UI”主要涉及到以下几个关键知识点: 1. **后台线程与主线程**:主线程是负责处理UI事件的线程,任何对UI的操作必须在这个线程上执行。后台线程则用于处理非UI相关的工作,如大数据计算、...

    使用线程添加数据

    当我们谈论“使用线程添加数据”时,我们通常是指在多线程环境下,如何通过不同的线程来实现数据的异步插入或者更新。这种方法可以极大地提高应用程序的性能,尤其是在大数据处理、网络I/O操作或用户界面响应速度...

    10.如何使用线程优先级?(Visual C++编程 源代码)

    10.如何使用线程优先级?(Visual C++编程 源代码)10.如何使用线程优先级?(Visual C++编程 源代码)10.如何使用线程优先级?(Visual C++编程 源代码)10.如何使用线程优先级?(Visual C++编程 源代码)10.如何...

    java应用程序中使用线程

    3.1 Java线程 3.2 创建线程 3.3 使用线程的缺点 3.3.1 初始启动变慢 3.3.2 资源利用 3.3.2 资源利用 3.4 线程管理 3.5 共享资源的使用同步 3.5.1 同步方法和同步代码块的嵌套调用...

    解决winform编程中使用线程界面卡死的案例

    标题中提到的“解决winform编程中使用线程界面卡死的案例”,主要是指通过创建后台线程来执行那些可能使UI卡死的操作,从而避免阻塞主线程。描述中提到了“用了委托”,这是在.NET框架中进行跨线程操作的关键技术。 ...

    Qt 下使用线程绘图

    为了解决这个问题,我们可以将绘图操作放到单独的线程中进行,这就是"Qt下使用线程绘图"的基本概念。下面将详细解释这一技术及其相关知识点。 1. **QThread类**:Qt提供的QThread类是线程的基础,它允许我们创建和...

    基于C++线程类,方便使用线程

    为了简化这一过程,我们可以创建一个封装好的线程类,如标题中提到的"基于C++线程类",以便更方便地使用线程。 这个线程类通常会包含以下几个核心功能: 1. **构造与销毁**:线程类的构造函数可能接受一个可调用...

    java作业 简单的摇骰子游戏、使用线程和swing、awt.zip

    简单的摇骰子游戏、使用线程和swing、awt.zip java作业。简单的摇骰子游戏、使用线程和swing、awt.zip java作业。简单的摇骰子游戏、使用线程和swing、awt.zip java作业。简单的摇骰子游戏、使用线程和swing、awt....

    如何使用线程优先级

    需要注意的是,过度使用线程优先级可能会导致优先级反转和优先级继承问题,这些问题可能导致系统性能下降甚至死锁。因此,合理设置线程优先级是非常重要的,通常只应为关键任务或需要快速响应的任务设置高优先级。 ...

    编程技巧:如何使用线程

    在本资料中,“编程技巧:如何使用线程”提供了关于理解和应用线程的关键知识点。 首先,线程的创建是多线程编程的基础。在Java中,可以通过实现`Runnable`接口或继承`Thread`类来创建线程。实现`Runnable`接口可以...

    C# 线程的使用 讲解了C#中使用线程的很多方法

    C# 线程的使用 讲解了C#中使用线程的很多方法 C# 线程的使用 讲解了C#中使用线程的很多方法

    WebService使用线程源码

    源码包括了服务器端使用线程代码及操作数据库与写入日志的实现,客户端如何调用WebService等内容

    vc++工作线程封装类

    这可能涉及到使用线程安全的数据结构,如线程局部存储(TLS)或互斥量保护的数据访问。 8. **线程的生命周期管理**:线程的创建、运行、停止和销毁应有明确的生命周期管理。避免创建过多线程导致系统资源耗尽,同时...

    Linux C语言函数大全.rarWindows 2000提供的常用对象可分成三类:核心应用服务、线程同步和线程间通讯。其中,开发人员可以使用线程同步对象来协调线程和进程的工作,以使其共享信息并执行任务。此类对象包括互锁数据、临界段、事件、互斥体和信号等。

    Windows 2000提供的常用对象可分成三类:核心应用服务、线程同步和...其中,开发人员可以使用线程同步对象来协调线程和进程的工作,以使其共享信息并执行任务。此类对象包括互锁数据、临界段、事件、互斥体和信号等。

    C#多线程学习 Thread类使用 线程等编程方法

    本文将深入探讨C#多线程编程,包括Thread类的使用以及线程同步的相关知识。 ### 1. Thread类介绍 Thread类是C#中处理线程的主要类,位于System.Threading命名空间下。通过实例化Thread类,我们可以创建新的线程并...

    C# 跨线程访问UI线程控件

    在C#中,由于使用线程和调用UI的线程属于两个不同的线程,如果在线程中直接设置UI元素的属性,此时就会出现跨线程错误。    下面介绍两种解决方案  第一种:使用控件自带的Invoke或者BeginInvoke方法。 Task....

    java多线程经典案例

    通过分析并实践`threadTest`案例,我们可以深入理解Java多线程的原理和使用技巧,为编写高效并发程序打下坚实基础。同时,也要注意多线程编程中的死锁、活锁和饥饿等问题,合理设计线程间的交互,避免出现不可预期的...

Global site tag (gtag.js) - Google Analytics