我在写“系统间通讯技术专栏”的时候,收到不少读者的反馈。其中有一部分读者但愿我抽空写一写本身关于对JAVA线程的使用经验和总结。巧的是,这个月我所在的技术团队也有不少同事跟我讨论关于JAVA中线程的操做。正好本月我工做也不是很忙,除了继续推动个人重点专栏“系统间通讯技术”外,能够更多的空余时间跟各位读者分享本身对JAVA线程技术的理解和使用经验。html
本人不才,应读者要求新开专栏,与各位读者分享本身对JAVA线程技术的理解和使用经验。这个专栏将分红两个部分:线程基础知识和锁知识。专栏的难度应该是我所开专栏中难度最低的一个,着重于线程基础知识的讲解,更适合JAVA初学者阅读,目的是但愿可以帮助你们提升codeing水平和程序质量。若是您是经验老道的高手也欢迎和本人讨论相关问题,对本人文章的论点进行勘误,您的支持是我写做的关键动力。固然本人的更多精力仍是放在继续完成“系统间通讯技术”这个专栏。(本系列的博客文章将不会置顶)java
线程是一个操做系统级别的概念。JAVA语言(包括其余编程语言)自己不建立线程;而是调用操做系统层提供的接口建立、控制、销毁线程实例。web
首先要说明的是,根据操做系统的不一样(Windows/Unix/Linux/其余),他们所支持的线程底层实现和操做效果也是不尽相同的。不过一个操做系统支持的线程至少会有四种状态:就绪、执行、阻塞和终结。线程在四种状态下进行切换,都是要消耗很多的CPU计算能力的。apache
而且根据操做系统使用线程的进程的不同,线程还分为用户线程和操做系统线程。操做系统线程(内核线程),是指操做系统内核为了完成硬件接口层操做,由操做系统内核建立的线程:例如I/O操做的内核线程,这些线程应用程序是不能干预的;用户线程,是指用户安装/管理的应用程序,为执行某一种操做,而由这个应用程序建立的线程。后文咱们讨论的JAVA线程,都是用户级线程。编程
线程在建立时,操做系统不会为这个线程分配独立的资源(除了必要的数据支撑)。一个应用程序(进程)下的全部线程,都是共享这个应用程序(进程)中的资源,例如这个应用程序的CPU资源、I/O资源、内存资源。多线程
如今基本上主流操做系统都支持多线程实现。即一个应用程序中(一个进程中),能够建立多个线程。一个应用程序下,各个线程间均可以进行通信、能够进行状态互操做。且一个进程中,至少有一个线程存在。编程语言
JAVA中提供了丰富的操做系统接口实现,帮助咱们进行线程操做。这些实现分布在java的java.lang基础包、java.io基础包和java.util.concurrent工具包当中;这个专栏所涉及到的代码示例也会从易到难向你们进行演示。咱们先来看看JAVA中最基本的线程操做实现(高手请绕行)。ide
java.lang.Thread类是JAVA中用于实现线程操做的最基本的类之一。您能够建立一个集成Thread类的子类来定义您本身的线程实现:svg
package test.thread.base;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.BasicConfigurator;
public class MyDefindThread extends Thread {
static {
BasicConfigurator.configure();
}
/** * 日志。必定要使用Log4j才行。不然你就用System.out吧 */
private static final Log LOGGER= LogFactory.getLog(MyDefindThread.class);
/* (non-Javadoc) * @see java.lang.Thread#run() */
@Override
public void run() {
Long threadId = this.getId();
MyDefindThread.LOGGER.info("线程(" + threadId + ")作了一些事情,而后结束了。");
}
public static void main(String[] args) throws Exception {
new MyDefindThread().start();
}
}
除了能够继承java.lang.Thread类来定义本身的线程外,您还能够实现java.lang.Runnable接口来定义一个线程(通常状况,咱们优先使用这种方式):工具
package test.thread.base;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.BasicConfigurator;
public class MyDefindRunnable implements Runnable {
static {
BasicConfigurator.configure();
}
/** * 日志。必定要使用Log4j才行。不然你就用System.out吧 */
private static final Log LOGGER= LogFactory.getLog(MyDefindThread.class);
/* (non-Javadoc) * @see java.lang.Runnable#run() */
@Override
public void run() {
// 获取当前线程的ID
long threadId = Thread.currentThread().getId();
MyDefindRunnable.LOGGER.info("线程(" + threadId + ")作了一些事情,而后结束了。");
}
public static void main(String[] args) throws Exception {
new Thread(new MyDefindRunnable()).start();
}
}
以上的两段代码都没有太多可讲解的。您能够在调试环境下观察到JAVA应用程序是如何运行线程的:
下一篇文章中,咱们将继续介绍Java所支持的线程间基本互操做,包括:阻塞、唤醒、终止等操做;而后介绍Java原生线程池的工做原理和基本操做。