线程:
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++中正确使用线程以及如何释放线程资源,并重点阐述joinable状态和detached状态的线程处理方式。 首先,我们需要了解线程的两种基本状态:joinable状态和detached状态。 1. **Joinable状态**...
以下是对"j2EE中使用线程的小DEMO"的详细解释。 在J2EE应用中,线程的使用主要有以下几个方面: 1. **Web容器中的线程**:当一个HTTP请求到达服务器时,Web容器(如Tomcat、Jetty等)会自动创建一个新的线程来处理...
标题“WPF 使用线程更新UI”主要涉及到以下几个关键知识点: 1. **后台线程与主线程**:主线程是负责处理UI事件的线程,任何对UI的操作必须在这个线程上执行。后台线程则用于处理非UI相关的工作,如大数据计算、...
当我们谈论“使用线程添加数据”时,我们通常是指在多线程环境下,如何通过不同的线程来实现数据的异步插入或者更新。这种方法可以极大地提高应用程序的性能,尤其是在大数据处理、网络I/O操作或用户界面响应速度...
10.如何使用线程优先级?(Visual C++编程 源代码)10.如何使用线程优先级?(Visual C++编程 源代码)10.如何使用线程优先级?(Visual C++编程 源代码)10.如何使用线程优先级?(Visual C++编程 源代码)10.如何...
3.1 Java线程 3.2 创建线程 3.3 使用线程的缺点 3.3.1 初始启动变慢 3.3.2 资源利用 3.3.2 资源利用 3.4 线程管理 3.5 共享资源的使用同步 3.5.1 同步方法和同步代码块的嵌套调用...
标题中提到的“解决winform编程中使用线程界面卡死的案例”,主要是指通过创建后台线程来执行那些可能使UI卡死的操作,从而避免阻塞主线程。描述中提到了“用了委托”,这是在.NET框架中进行跨线程操作的关键技术。 ...
为了解决这个问题,我们可以将绘图操作放到单独的线程中进行,这就是"Qt下使用线程绘图"的基本概念。下面将详细解释这一技术及其相关知识点。 1. **QThread类**:Qt提供的QThread类是线程的基础,它允许我们创建和...
为了简化这一过程,我们可以创建一个封装好的线程类,如标题中提到的"基于C++线程类",以便更方便地使用线程。 这个线程类通常会包含以下几个核心功能: 1. **构造与销毁**:线程类的构造函数可能接受一个可调用...
简单的摇骰子游戏、使用线程和swing、awt.zip java作业。简单的摇骰子游戏、使用线程和swing、awt.zip java作业。简单的摇骰子游戏、使用线程和swing、awt.zip java作业。简单的摇骰子游戏、使用线程和swing、awt....
需要注意的是,过度使用线程优先级可能会导致优先级反转和优先级继承问题,这些问题可能导致系统性能下降甚至死锁。因此,合理设置线程优先级是非常重要的,通常只应为关键任务或需要快速响应的任务设置高优先级。 ...
在本资料中,“编程技巧:如何使用线程”提供了关于理解和应用线程的关键知识点。 首先,线程的创建是多线程编程的基础。在Java中,可以通过实现`Runnable`接口或继承`Thread`类来创建线程。实现`Runnable`接口可以...
C# 线程的使用 讲解了C#中使用线程的很多方法 C# 线程的使用 讲解了C#中使用线程的很多方法
源码包括了服务器端使用线程代码及操作数据库与写入日志的实现,客户端如何调用WebService等内容
这可能涉及到使用线程安全的数据结构,如线程局部存储(TLS)或互斥量保护的数据访问。 8. **线程的生命周期管理**:线程的创建、运行、停止和销毁应有明确的生命周期管理。避免创建过多线程导致系统资源耗尽,同时...
Windows 2000提供的常用对象可分成三类:核心应用服务、线程同步和...其中,开发人员可以使用线程同步对象来协调线程和进程的工作,以使其共享信息并执行任务。此类对象包括互锁数据、临界段、事件、互斥体和信号等。
本文将深入探讨C#多线程编程,包括Thread类的使用以及线程同步的相关知识。 ### 1. Thread类介绍 Thread类是C#中处理线程的主要类,位于System.Threading命名空间下。通过实例化Thread类,我们可以创建新的线程并...
在C#中,由于使用线程和调用UI的线程属于两个不同的线程,如果在线程中直接设置UI元素的属性,此时就会出现跨线程错误。 下面介绍两种解决方案 第一种:使用控件自带的Invoke或者BeginInvoke方法。 Task....
使用`SuspendThread`和`ResumeThread`函数可以暂停和恢复线程,而`TerminateThread`函数则用于强制结束线程。需要注意的是,线程的管理必须谨慎,以免引起系统不稳定。 6. **错误处理**:多线程编程中,错误处理至...