一:JAVA中的线程
在java中线程的应用类主要在下面两个包中:
- java.lang
- java.util. concurrent
下图体现的是Java中最基础的线程类的关系拓扑图:
来看看java.lang.Runnable接口的源码:
package java.lang; public interface Runnable { /** * When an object implementing interface <code>Runnable</code> is used * to create a thread, starting the thread causes the object's * <code>run</code> method to be called in that separately executing * thread. * <p> * The general contract of the method <code>run</code> is that it may * take any action whatsoever. * * @see java.lang.Thread#run() */ public abstract void run(); }
源码说明:
(1) Runnable中只有一个run()方法,且其类型是abstract()
(2) run()的解释:使用实现接口 Runnable 的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用对象的 run 方法。 方法 run 的常规协定是,它可能执行任何所需的动作。
Java.lang.Thread的源码:
package thread; package java.lang; ... /** * 线程是程序中的执行线程,Java 虚拟机允许应用程序并发地运行多个执行线程。 * 每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。每一个线 * 程都可以或不可以标记为一个守护线程。当某个线程中运行的代码创建一个新 * Thread对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅 * 当创建线程是守护线程时,新线程才是守护线程。 * 当JAVA虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的 * main方法)。Java 虚拟机会继续执行线程,直到下列任一情况出现时为止: * 1:调用了Runtime类的exit()方法,并且安全管理器允许退出操作发生。 * 2:所有的非守护线程都停止运行,无论是通过从对 run 方法的调用中返回,还 是通过抛出一个传播到 run 方法之外的异常。 */ public class Thread implements Runnable { /* 确保registerNatives是client(端)做的第一件事。 */ private static native void registerNatives(); static { registerNatives(); } private char name[]; private int priority; private Thread threadQ; private long eetop; /* 线程是否单步 */ private boolean single_step; /* 线程是否是守护线程。 */ private boolean daemon = false; /* JVM state */ private boolean stillborn = false; /* 什么将被执行 */ private Runnable target; /* 线程组 */ private ThreadGroup group; /* 这个线程上下文类加载器 */ private ClassLoader contextClassLoader; /* The inherited AccessControlContext of this thread */ private AccessControlContext inheritedAccessControlContext; /* 用于自动编号的匿名线程 */ private static int threadInitNumber; private static synchronized int nextThreadNum() { return threadInitNumber++; } /**线程的初始状态:not yet started/ private volatile int threadStatus = 0; /**一个线程可以拥有的最低优先级为:1**/ public final static int MIN_PRIORITY = 1; /**分配给一个线程的缺省优先级为: 5*/ public final static int NORM_PRIORITY = 5; /**一个线程可以拥有的最高优先级为:10**/ public final static int MAX_PRIORITY = 10; /**暂停当前正在执行的线程对象,并执行其他线程。**/ public static native void yield(); /**在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。*/ public static native void sleep(long millis) throws InterruptedException; /** * 在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。 * 参数:millis 以毫秒为单位的休眠时间。 * nanos 要休眠的另外 0-999999 纳秒。 */ public static void sleep(long millis, int nanos)throws InterruptedException { ... } /**初始化线程**/ private void init(ThreadGroup g, Runnable target, String name,long stackSize) {} /** 分配新的 Thread 对象. **/ public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0);} /** * 分配新的 Thread 对象. * 参数:target - 任务 */ public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0);} /** * 分配新的 Thread 对象. * 参数:name - 新线程的名称 * target - 任务 */ public Thread(Runnable target, String name) { init(null, target, name, 0);} /** * 分配新的 Thread 对象. * 参数:name - 新线程的名称 */ public Thread(String name) { init(null, null, name, 0); } /** * 分配新的 Thread 对象. * 参数:group - 线程组 * target - 任务 * 异常:SecurityException - 如果当前线程无法在指定的线程组中创建线程 public Thread(ThreadGroup group, Runnable target) { init(group, target, "Thread-" + nextThreadNum(), 0); } /** * 分配新的 Thread 对象. * 参数:name - 新线程的名称 * group - 线程组 * 异常:SecurityException - 如果当前线程无法在指定的线程组中创建线程 */ public Thread(ThreadGroup group, String name) { init(group, null, name, 0); } /** * 分配新的 Thread 对象. * 参数:name - 新线程的名称 * target - 任务 * group * 异常:SecurityException 如果当前线程不能在指定的线程组中创建线程或无法重写上下文类加载器的方法。 */ public Thread(ThreadGroup group, Runnable target, String name) { init(group, target, name, 0); } /** * 分配新的Thread对象,以便将target作为其运行对象,将指定的name作为其名称,属于由组提到的线程组,并具有指定的堆栈大小。 * 参数:name - 新线程的名称 target - 任务 group - 线程组 stackSize - 栈大小 * 异常:SecurityException 如果当前线程不能在指定的线程组中创建线程 */ public Thread(ThreadGroup group, Runnable target, String name,long stackSize) { init(group, target, name, stackSize); } /** * 使该线程开始执行; Java虚拟机调用该线程的run方法。 * 其结果是两个线程同时运行,当前线程(该线程从调用start()方法返回)和另一个线程(该线程执行它的run()方法)。 * 多次启动一个线程是无效的。 特别是当一个线程完成后,再被启动。 * @exception IllegalThreadStateException 如果线程已经启动 */ public synchronized void start() {...} private native void start0(); /** * 如果该线程使用了一个单独的Runnable进行对象构造,运行对象,则Runnable对象的run方法被调用。 * 否则,此方法不执行任何操作并返回。 */ @Override public void run() { if (target != null) { target.run(); } } /**该方法被系统调用,主要是退出前进行清理工作**/ private void exit() { if (group != null) { group.threadTerminated(this); group = null; } /* Aggressively null out all reference fields: see bug 4006245 */ target = null; /* Speed the release of some of these resources */ threadLocals = null; inheritableThreadLocals = null; inheritedAccessControlContext = null; blocker = null; uncaughtExceptionHandler = null; } }
源码说明:
(1) 其实现了Runnable接口,而Runnable接口有一个run()方法,所以Thread也实现了该方法。
(2) 从其构造函数中的如下代码:
init(null, null, "Thread-" + nextThreadNum(), 0);
可以看出,线程名称创建的规则是:”Thread-”+创建的线程的个数(第几个线程)
二:JAVA中线程的状态
1) New(新建) 新建的、至今尚未启动的线程处于这种状态。
2) Runnable(可运行状态): 包括就绪、运行中两个状态
(1)Ready(就绪): 程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权 。
(2)Running(运行中): 可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,正在执行程序代码。
3) Wait/Blocked(暂停运行/阻塞):
Wait/Blocked状态是指线程因为某种原因放弃了cpu 使用权,即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。Wait/Blocked的情况分三种:
(1). Timed Waiting:调用如下方法,线程处于暂停运行状态,直到等待时间已过,线程重新转入可运行(runnable)状态。
sleep(long timeout) wait(long timeout) wait(long timeout, int nanos) join(long millis) join(long millis, int nanos) LockSupport.parkNanos(long nanos) LockSupport.parkUntil(long deadline)
(2). Waiting: 某一等待线程的线程状态。某一线程因为调用下列方法之一而处于等待状态,直到针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
不带超时值的 Object.wait() 不带超时值的 Thread.join() LockSupport.park()
(3). Blocked:受阻塞并且正在等待监视器锁的某一线程的线程状态。处于受阻塞状态的某一线程正在等待监视器锁,以便进入一个同步的块/方法,或者在调用 Object.wait 之后再次进入同步的块/方法。
4) Terminated(终止):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。
线程的生命周期图
三:线程的分类
Java线程可以分两类:
1.守护线程(daemon threads)
守护线程通常为普通线程提供服务,它们通常有一个无限循环,等待服务请求或执行线程的任务,在没有其他的非守护线程运行时,守护线程将停止工作。即使你不创建任何线程,Java应用程序在默认情况下创建多个线程。他们大多是守护线程,主要用于处理任务,如垃圾收集或JMX。
守护线程的特点:
- 优先级非常低
- 只有当同一个程序的任何其他线程正在运行时执行。
- 当线程只剩下守护线程的时候,JVM就会退出.但是如果还有其他的任意一个用户线程还在,JVM就不会退出.
2.非守护线程 (non-daemon threads)或普通线程或用户线程(user threads)
用户线程和守护线程两者几乎没有区别,唯一的不同之处就在于虚拟机的离开:如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。 因为没有了被守护者,守护线程也就没有工作可做了,也就没有继续运行程序的必要了
在JAVA中通过调方法Thread.setDaemon(true)将线程转为守护线程。但需要注意的有:
1)但必须在调Thread.start()方法之前,因为一旦线程正在运行,你不能修改它的守护进程的状态。
2)在Daemon线程中产生的新线程也是Daemon的
3)守护线程应该永远不去访问固有资源,如文件、数据库,因为它会在任何时候甚至在一个操作的中间发生中断。
举例:
package thread; public class DaemonTest { public static void main(String[] args) { new WorkerThread().start(); try { Thread.sleep(7500); } catch (InterruptedException e) {} System.out.println("Main Thread ending") ; } } class WorkerThread extends Thread { public WorkerThread() { System.out.println("线程是否为守护线程: "+this.isDaemon()); // When false, (i.e. when it's a user thread), // the Worker thread continues to run. // When true, (i.e. when it's a daemon thread), // the Worker thread terminates when the main // thread terminates. setDaemon(true) ; System.out.println("线程是否为守护线程: "+this.isDaemon()); } public void run() { int count=0 ; while (true) { System.out.println("Hello from Worker "+count++) ; try { sleep(5000); } catch (InterruptedException e) {} } } }
参考资料:
http://blog.csdn.net/yyc1023/article/details/17428633
http://uule.iteye.com/blog/1100799
http://my.oschina.net/mingdongcheng/blog/139263
http://blog.csdn.net/yyc1023/article/details/17428633
http://www1.huachu.com.cn/read/readbookinfo.asp?sectionid=1000005042
http://lavasoft.blog.51cto.com/62575/99153
http://www.cnblogs.com/jinglingJuly/archive/2013/06/02/3113397.html
http://52android.blog.51cto.com/2554429/468031/
http://www.uml-diagrams.org/examples/java-6-thread-state-machine-diagram-example.html
http://www.cjsdn.net/doc/jdk50/java/lang/Thread.State.html
http://architects.dzone.com/articles/how-analyze-java-thread-dumps
http://stackoverflow.com/questions/2213340/what-is-daemon-thread-in-java
相关推荐
### Java多线程操作数据库:深入解析与应用 在当今高度并发的应用环境中,Java多线程技术被广泛应用于处理数据库操作,以提升系统的响应速度和处理能力。本文将基于一个具体的Java多线程操作数据库的应用程序,深入...
### JAVA中的单线程与多线程概念解析 #### 单线程的理解 在Java编程环境中,单线程指的是程序执行过程中只有一个线程在运行。这意味着任何时刻只能执行一个任务,上一个任务完成后才会进行下一个任务。单线程模型...
java多线程PPT 多线程基本概念 创建线程的方式 线程的挂起与唤醒 多线程问题
Java多线程编程实战指南(核心篇) 高清pdf带目录 随着现代处理器的生产工艺从提升处理器主频频率转向多核化,即在一块芯片上集成多个处理器内核(Core),多核处理器(Multicore Processor)离我们越来越近了――如今...
Java多线程是Java编程语言中一个非常重要的概念,它允许开发者在一个程序中创建多个执行线程并行运行,以提高程序的执行效率和响应速度。在Java中,线程的生命周期包含五个基本状态,分别是新建状态(New)、就绪...
Java多线程机制是Java编程中至关重要的一部分,它允许程序同时执行多个任务,提升应用程序的效率和响应性。以下是对各个知识点的详细说明: 9.1 Java中的线程: Java程序中的线程是在操作系统级别的线程基础上进行...
Java多线程是Java编程中的一个重要概念,它允许程序同时执行多个任务,提高了程序的效率和响应速度。在Java中,实现多线程有两种主要方式:继承Thread类和实现Runnable接口。 1. 继承Thread类: 当我们创建一个新...
Java多线程是Java编程中的重要概念,尤其在如今的多核处理器环境下,理解并熟练掌握多线程技术对于提高程序性能和响应速度至关重要。本资料详细讲解了Java多线程的原理,并提供了丰富的实战代码,非常适合Java初学者...
#### 二、Java多线程分页查询原理及实现 ##### 1. 分页查询基础概念 分页查询是指在查询数据时,将数据分成多个页面展示,而不是一次性返回所有数据。这种方式能够有效地减少单次查询的数据量,从而提高查询速度和...
首先,理解Java多线程的基本概念至关重要。Java通过Thread类和Runnable接口来支持多线程。创建一个新线程通常有两种方式:继承Thread类并重写run()方法,或者实现Runnable接口并提供run()方法。在run()方法中编写...
Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,极大地提升了程序的效率和性能。在Java中,实现多线程有两种主要方式:通过实现Runnable接口或者继承Thread类。本案例将深入探讨Java多线程中的关键...
本文将基于"java 多线程并发实例"这个主题,深入探讨Java中的多线程并发概念及其应用。 首先,我们要了解Java中的线程。线程是程序执行的基本单元,每个线程都有自己的程序计数器、虚拟机栈、本地方法栈,而共享堆...
Java多线程设计模式是Java开发中的核心概念,它涉及到如何高效、安全地在多个执行线程之间共享资源和协调任务。设计模式是解决特定问题的成熟方案,它们是编程经验的结晶,可以帮助开发者在面临多线程挑战时快速找到...
《Java多线程编程实战指南》这本书深入浅出地讲解了Java多线程的核心概念和实战技巧,分为核心篇和设计模式篇,旨在帮助开发者掌握并应用多线程技术。 1. **线程基础** - **线程的创建**:Java提供了两种创建线程...
《JAVA多线程教学演示系统》是一篇深入探讨JAVA多线程编程的论文,它针对教育领域中的教学需求,提供了一种生动、直观的演示方式,帮助学生更好地理解和掌握多线程技术。这篇论文的核心内容可能包括以下几个方面: ...
《Java多线程编程实战指南(核心篇)》以基本概念、原理与方法为主线,辅以丰富的实战案例和生活化实例,并从Java虚拟机、操作系统和硬件多个层次与角度出发,循序渐进、系统地介绍Java平台下的多线程编程核心技术及...
在本文中,我们将深入浅出Java多线程编程的世界,探索多线程编程的基本概念、多线程编程的优点、多线程编程的缺点、多线程编程的应用场景、多线程编程的实现方法等内容。 一、多线程编程的基本概念 多线程编程是指...
Java多线程是Java编程中的核心概念,它允许程序同时执行多个任务,提高了系统的效率和响应性。在Java中,多线程的实现主要通过两种方式:继承Thread类和实现Runnable接口。理解并掌握多线程的使用对于任何Java开发者...
书中详细介绍了Java多线程的核心概念,如线程的创建、启动、同步、协作以及生命周期管理。读者将学习如何通过实现Runnable接口或继承Thread类来创建线程,以及如何使用Executor框架来管理线程池。 此外,书中还深入...
JAVA多线程练习题答案详解 在本文中,我们将对 JAVA 多线程练习题的答案进行详细的解释和分析。这些题目涵盖了 JAVA 多线程编程的基本概念和技术,包括线程的生命周期、线程同步、线程状态、线程优先级、线程安全等...