- 浏览: 216241 次
- 性别:
- 来自: 北京
文章分类
实现多线程的两种方式:继承Thread类或是实现Runnable接口,推荐后者
线程所拥有的状态:初始状态,可运行状态,运行状态,阻塞状态,锁池状态,等待队列,终止状态。
线程的生命状态:
1.当线程类被创建后就进入初始化状态。
2.当调用.start()方法时就拿到对象锁,进入可运行状态(一旦获取cpu资源就会进入运行状态)
3.当处于可运行状态的线程拿到cpu分配的时间片就进入运行状态。
3.1.如果处于运行状态的线程的main方法或是run方法执行完,线程就进入终止状态。
3.2.如果当前处于运行状态的线程调用sleep()方法或是join()方法,线程就进入阻塞状态。此时不释放资源(主要指对象锁)。当睡眠时间结束后进入可运行状态,等待获取cpu的时间片。
3.3.当处于运行状态的当前线程调用yield方法,线程就会放弃当前时间片回到可运行状态。和其他线程再次竞争。
3.4.当进入运行状态的线程调用wait方法后就会进入等待状态。只有调用了notify(只唤醒一个线程不确定唤醒哪个线程)或是notifyAll方法会后进入锁池状态。拿到对象锁标记后会进入可运行状态。
3.5.当运行状态的线程发现要使用的资源被同步时,会进入锁池状态,当拿到对象锁后会进入可运行状态。
注:yield就是当当前线程临时暂停让其他线程运行。
join方法表示run方法完成后台程序在继续执行。也就是合并子线程到主线程里,是程序顺序执行。
如:thread1.join(); // 等线程thread1结束后再继续执行
使用interrupt方法终止线程
使用interrupt方法来终端线程可分为两种情况:
(1)线程处于阻塞状态,如使用了sleep方法。
(2)使用while(!isInterrupted()){...}来判断线程是否被中断。
在第一种情况下使用interrupt方法,sleep方法将抛出一个InterruptedException例外,而在第二种情况下线程将直接退出。
在Thread类中有两个方法可以判断线程是否通过interrupt方法被终止。一个是静态的方法interrupted(),一个是非静态的方法isInterrupted(),这两个方法的区别是interrupted用来判断当前线是否被中断,而isInterrupted可以用来判断其他线程是否被中断
线程声明周期总结:
当一个线程类被new出来以后就进入了初始化状态,当调用线程的start的方法以后就进入可运行状态,可运行状态表示该线程已经具备了运行条件就等待分配cpu的时间片就可以运行了。当获取到时间片以后就进入了运行状态。
情况一:进入运行状态后,执行完main方法等就进入终结状态。
情况二:进入运行状态后,调用Thread的sleep方法或是join方法,就进入阻塞状态当,当睡眠时间过了后就进入可运行状态,等待获取时间片接着运行。
情况三:进入运行状态以后,调用yield方法后会放弃时间片,进入可运行状态,再次获取时间片后才接这运行。
情况四:当进入运行状态后,当要调用的资源已经被其他线程占用,即不能拿到对象锁,就会进入锁池,先进先拿,等拿到对象锁后会进入可运行状态,活取到时间片后接着运行。
情况5:当进入运行状态后,当调用对象的wait方法后,会进入等待队列,当调用notify方法或是notifyAll方法后进入锁池。拿取到对象锁后,再进入可运行状态
线程one经过了500ms的sleep后,在某一时刻再次获得时间片,它将接着上一次的断点运行
死锁实例
1.public class DeadLockOneRunnable implements Runnable {
2. private byte [] bytes;
3. public DeadLockOneRunnable (byte [] bytes) {
4. this.bytes= bytes;
5. }
6. @Override
7. public void run() {
8. synchronized (bytes) {
9. while(true) {
10. System.out.println(Thread.currentThread().getName() + "is running...");
11. }
12. }
13. }
14.
15. public static void main(String[] args) {
16. byte [] bytes = new byte[0];
17. DeadLockOneRunnable run = new DeadLockOneRunnable(bytes);
18. Thread thread = new Thread(run, "thread");
19. thread.start();
20. synchronized (bytes) {
21. try {
22. thread.join();
23. } catch (InterruptedException e) {
24. e.printStackTrace();
25. }
26. }
27. System.out.println("main thread run over .");
28. }
29.}
public class DeadLockOneRunnable implements Runnable {
private byte [] bytes;
public DeadLockOneRunnable (byte [] bytes) {
this.bytes= bytes;
}
@Override
public void run() {
synchronized (bytes) {
while(true) {
System.out.println(Thread.currentThread().getName() + "is running...");
}
}
}
public static void main(String[] args) {
byte [] bytes = new byte[0];
DeadLockOneRunnable run = new DeadLockOneRunnable(bytes);
Thread thread = new Thread(run, "thread");
thread.start();
synchronized (bytes) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("main thread run over .");
}
} 说明:在main线程中获得了对象bytes的lock,然后线程thread通过join()方法,则主线程main必须要等到thread线程终止后才可以继续往下运行。但是,当线程thread运行后,发现在其run()方法内部synchronized(bytes),那么线程thread也需要持有对象bytes的lock才可以运行。此时的情况为main线程持有对象bytes的lock等待线程thread运行终止后运行,而线程thread又需要对象bytes的lock被释放;两个线程相互等待彼此的资源,产生死锁。
线程所拥有的状态:初始状态,可运行状态,运行状态,阻塞状态,锁池状态,等待队列,终止状态。
线程的生命状态:
1.当线程类被创建后就进入初始化状态。
2.当调用.start()方法时就拿到对象锁,进入可运行状态(一旦获取cpu资源就会进入运行状态)
3.当处于可运行状态的线程拿到cpu分配的时间片就进入运行状态。
3.1.如果处于运行状态的线程的main方法或是run方法执行完,线程就进入终止状态。
3.2.如果当前处于运行状态的线程调用sleep()方法或是join()方法,线程就进入阻塞状态。此时不释放资源(主要指对象锁)。当睡眠时间结束后进入可运行状态,等待获取cpu的时间片。
3.3.当处于运行状态的当前线程调用yield方法,线程就会放弃当前时间片回到可运行状态。和其他线程再次竞争。
3.4.当进入运行状态的线程调用wait方法后就会进入等待状态。只有调用了notify(只唤醒一个线程不确定唤醒哪个线程)或是notifyAll方法会后进入锁池状态。拿到对象锁标记后会进入可运行状态。
3.5.当运行状态的线程发现要使用的资源被同步时,会进入锁池状态,当拿到对象锁后会进入可运行状态。
注:yield就是当当前线程临时暂停让其他线程运行。
join方法表示run方法完成后台程序在继续执行。也就是合并子线程到主线程里,是程序顺序执行。
如:thread1.join(); // 等线程thread1结束后再继续执行
使用interrupt方法终止线程
使用interrupt方法来终端线程可分为两种情况:
(1)线程处于阻塞状态,如使用了sleep方法。
(2)使用while(!isInterrupted()){...}来判断线程是否被中断。
在第一种情况下使用interrupt方法,sleep方法将抛出一个InterruptedException例外,而在第二种情况下线程将直接退出。
在Thread类中有两个方法可以判断线程是否通过interrupt方法被终止。一个是静态的方法interrupted(),一个是非静态的方法isInterrupted(),这两个方法的区别是interrupted用来判断当前线是否被中断,而isInterrupted可以用来判断其他线程是否被中断
线程声明周期总结:
当一个线程类被new出来以后就进入了初始化状态,当调用线程的start的方法以后就进入可运行状态,可运行状态表示该线程已经具备了运行条件就等待分配cpu的时间片就可以运行了。当获取到时间片以后就进入了运行状态。
情况一:进入运行状态后,执行完main方法等就进入终结状态。
情况二:进入运行状态后,调用Thread的sleep方法或是join方法,就进入阻塞状态当,当睡眠时间过了后就进入可运行状态,等待获取时间片接着运行。
情况三:进入运行状态以后,调用yield方法后会放弃时间片,进入可运行状态,再次获取时间片后才接这运行。
情况四:当进入运行状态后,当要调用的资源已经被其他线程占用,即不能拿到对象锁,就会进入锁池,先进先拿,等拿到对象锁后会进入可运行状态,活取到时间片后接着运行。
情况5:当进入运行状态后,当调用对象的wait方法后,会进入等待队列,当调用notify方法或是notifyAll方法后进入锁池。拿取到对象锁后,再进入可运行状态
线程one经过了500ms的sleep后,在某一时刻再次获得时间片,它将接着上一次的断点运行
死锁实例
1.public class DeadLockOneRunnable implements Runnable {
2. private byte [] bytes;
3. public DeadLockOneRunnable (byte [] bytes) {
4. this.bytes= bytes;
5. }
6. @Override
7. public void run() {
8. synchronized (bytes) {
9. while(true) {
10. System.out.println(Thread.currentThread().getName() + "is running...");
11. }
12. }
13. }
14.
15. public static void main(String[] args) {
16. byte [] bytes = new byte[0];
17. DeadLockOneRunnable run = new DeadLockOneRunnable(bytes);
18. Thread thread = new Thread(run, "thread");
19. thread.start();
20. synchronized (bytes) {
21. try {
22. thread.join();
23. } catch (InterruptedException e) {
24. e.printStackTrace();
25. }
26. }
27. System.out.println("main thread run over .");
28. }
29.}
public class DeadLockOneRunnable implements Runnable {
private byte [] bytes;
public DeadLockOneRunnable (byte [] bytes) {
this.bytes= bytes;
}
@Override
public void run() {
synchronized (bytes) {
while(true) {
System.out.println(Thread.currentThread().getName() + "is running...");
}
}
}
public static void main(String[] args) {
byte [] bytes = new byte[0];
DeadLockOneRunnable run = new DeadLockOneRunnable(bytes);
Thread thread = new Thread(run, "thread");
thread.start();
synchronized (bytes) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("main thread run over .");
}
} 说明:在main线程中获得了对象bytes的lock,然后线程thread通过join()方法,则主线程main必须要等到thread线程终止后才可以继续往下运行。但是,当线程thread运行后,发现在其run()方法内部synchronized(bytes),那么线程thread也需要持有对象bytes的lock才可以运行。此时的情况为main线程持有对象bytes的lock等待线程thread运行终止后运行,而线程thread又需要对象bytes的lock被释放;两个线程相互等待彼此的资源,产生死锁。
发表评论
-
JVM启动时指定-Dfile.encoding="UTF8"的作用
2013-10-17 13:50 2393简单来说就是指定JVM默认的编码方式 java io中很多方法 ... -
java多线程 小记
2012-04-15 14:49 0thread join的方法 http://blog.csdn ... -
浅析多线程
2012-04-08 22:35 0线程组 线程是被 ... -
多线程意外中断处理
2012-04-08 20:54 0本文转自:http://peirenlei.iteye.com ... -
多线程项目学习
2012-04-08 20:35 0线程组的作用: ThreadGroup类中的某些方法,可以对线 ... -
java 静态成员变量的内存分配
2012-04-06 10:28 0静态成员变量是属于类变量,即当JVM加载class文件到虚拟机 ... -
深度克隆与浅克隆
2012-04-05 16:31 1173要想实现某个对象的克隆需要该对象实现java.lang.Clo ... -
修改图片大小并添加水印
2012-03-29 13:47 1323import java.awt.*; import java. ... -
JVM的内存分配
2012-03-16 10:06 0Java里的堆(heap)栈(stack)和方法区(metho ... -
HashMap添加数据的过程
2012-03-14 22:18 7134当添加的元素的key为null ... -
几种classloader的加载范围
2012-02-28 12:43 1364Bootstrap class loader:最顶级的clas ... -
利用正则表达式获取网页中多处重复出现的标签数据
2012-02-21 11:21 2737public static void main(String[ ... -
标准的URLConnection请求
2012-01-13 16:39 0只写了主要的代码 URL url = new URL(urlS ... -
常用的ClassLoader的加载范围
2012-01-13 13:53 1434WebAppClassLoader装载器装作文件的范围: 会加 ... -
ClassLoader.getSystemClassLoader().loadClass()和Class.forName()的区别
2012-01-13 13:08 0class A { static { System.ou ... -
httpClient超时解决办法
2012-01-12 16:47 0DefaultHttpClient: 请求超时 httpcli ... -
项目中的使用技巧小记
2012-01-10 21:11 612实现数据在多线程之间的共享: 因为线程的成员变量是各个该线程实 ... -
ThreadLocal
2012-01-10 08:55 1445ThreadLocal是实现线程范围内的数据共享,即不同线程获 ... -
线程加锁优化
2012-01-08 13:19 0实际上,在某些classes中,这种instance方法的同步 ... -
实现多线程使用继承Thread类和Runnable的原因
2012-01-03 15:09 1404我们都知道实现多线程的两种方式,一种是继承Thread类,另一 ...
相关推荐
多线程生命周期图解,一分钟了解线程从生到死全过程,图文并茂,通俗易懂,容易记忆。独家原创。欢迎下载。
Java多线程生命周期的讲解,很详细,希望能帮到大家
我根据自己的理解画的这个线程生命流程图,希望对你们有点点的帮助吧!!!
### Java多线程之线程的生命周期和状态控制 #### 一、线程的生命周期 在Java中,线程的生命周期是指线程从创建到结束的整个过程。根据线程的状态变化,我们可以将线程的生命周期划分为以下几个阶段: 1. **新建...
线程生命周期的终点是死亡状态。线程在以下三种情况下结束:`run()`方法执行完毕、执行过程中抛出未捕获异常或错误,或者调用已过时的`stop()`方法。 6. 等待(Waiting): 从JDK1.5开始,线程可以进入等待状态,这...
初学Java多线程线程的生命周期.pdf
在探讨Java多线程和线程生命周期时,我们首先应该明确,Java多线程是Java语言支持并发编程的一个重要特性,其允许同时执行多个任务,以提高程序的执行效率和改善用户体验。Java中的每个线程都有自己的生命周期,由一...
Java线程生命周期是Java编程中的核心概念,它关乎...总之,理解和掌握Java线程生命周期对于编写高效的并发程序至关重要,它涉及到线程的创建、执行、同步、通信以及资源释放等多个方面,是Java程序员必备的基础知识。
模板可能封装了检查和管理线程状态的方法,帮助开发者更好地控制线程生命周期。 6. **异常处理**:多线程环境下的异常处理需要特别注意,因为一个线程的异常可能会中断其他线程。大漠的模板可能包含了优雅的异常...
线程基础,线程池,生命周期
5. 线程生命周期管理:包括启动、等待、停止和销毁线程的方法,确保程序在所有线程结束后能够正常退出。 深入学习这个例子,开发者可以掌握如何在实际项目中应用多线程技术,提升软件性能,同时理解如何利用专门的...
线程的生命周期包括创建、运行、等待、结束等阶段,开发者需要合理管理线程,防止资源浪费或死锁。 三、多参数传递 在单线程中,我们可以直接通过变量或参数传递数据。但在多线程环境中,由于线程间的并发执行,...
在Java中,理解线程的生命周期是掌握多线程编程的关键。线程的生命周期包含了五个主要状态:新建、就绪、运行、阻塞和死亡。 1. **新建状态**(New): 当我们使用`Thread`类创建一个新的线程对象时,线程处于新建...
在Android应用开发中,Activity是用户界面的基本组件,它的生命周期管理是开发者必须深入理解的关键概念。线程优先级则是多线程编程中的一个重要属性,它影响着程序的执行顺序。异常销毁是Android系统处理错误时的一...
6. **线程生命周期管理**:创建线程时要考虑其生命周期,避免过多的线程创建和销毁导致的性能损失。 五、示例代码 这里提供一个简单的PB.NET多线程示例: ```csharp using System.Threading; public class ...
本文将深入探讨Java多线程中的线程生命周期,以及如何控制线程的状态转换。 线程的生命周期通常包括五个基本状态:新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和终止(Terminated)。下面...
这些题目涵盖了 JAVA 多线程编程的基本概念和技术,包括线程的生命周期、线程同步、线程状态、线程优先级、线程安全等方面。 一、单项选择题 在单项选择题中,我们可以看到各种关于 JAVA 多线程编程的基本概念和...
3. **线程生命周期**:Java线程经历新建、就绪、运行、阻塞和终止五个状态。了解这些状态及其转换对于理解和控制线程行为至关重要。 4. **线程同步**:为了解决多线程环境下的数据安全问题,Java提供了synchronized...
开发者在使用多线程时需要注意避免这些问题,合理规划线程的生命周期,以及合理使用同步机制。 综上所述,这个压缩包中的内容是关于易语言下实现多线程程序的实例,包括源代码和使用说明,对于想要学习易语言多线程...
浅析Java语言中线程的生命周期及实现方式 Java语言中的线程(Thread)是指在同一个进程中可以并发执行的多个控制流程。线程是Java语言中定义的非常重要...了解线程的生命周期和实现方式是Java语言中多线程开发的基础。