Java多线程概述

时间:2022-12-28 17:30:26

多线程编程是java编程重要的一个方面。对于初学者,线程、进程、锁等概念比较难理解。这篇文章主要介绍多线程的概念,java实现方式,java多线程效率分析等内容。

多线程

多线程概念

线程(thread),有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。
线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。
一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。
线程是程序中一个单一的顺序控制流程.在单个程序中同时运行多个线程完成不同的工作,称为多线程.
多线程编程的目的,就是”最大限度地利用CPU资源”,当某一线程的处理不需要占用CPU而只和I/O,OEMBIOS等资源打交道时,让需要占用CPU资源的其它线程有机会获得CPU资源。每个程序执行时都会产生一个进程,而每一个进程至少要有一个主线程。这个线程其实是进程执行的一条线索,除了主线程外你还可以给进程增加其它的线程,也即增加其它的执行线索,由此在某种程度上可以看成是给一个应用程序增加了多任务功能。

多线程与多进程

进程和线程都是操作系统的概念。进程是应用程序的执行实例,每个进程是由私有的虚拟地址空间、代码、数据和其它各种系统资源组成,进程在运行过程中创建的资源随着进程的终止而被销毁,所使用的系统资源在进程终止时被释放或关闭。
线程是进程内部的一个执行单元。系统创建好进程后,实际上就启动执行了该进程的主执行线程,主执行线程以函数地址形式,比如说main或WinMain函数,将程序的启动点提供给Windows系统。主执行线程终止了,进程也就随之终止。
每一个进程至少有一个主执行线程,它无需由用户去主动创建,是由系统自动创建的。用户根据需要在应用程序中创建其它线程,多个线程并发地运行于同一个进程中。一个进程中的所有线程都在该进程的虚拟地址空间中,共同使用这些虚拟地址空间、全局变量和系统资源,所以线程间的通讯非常方便,多线程技术的应用也较为广泛。多线程可以实现并行处理,避免了某项任务长时间占用CPU时间。要说明的一点是,目前大多数的计算机都是单处理器(CPU)的,为了运行所有这些线程,操作系统为每个独立线程安排一些CPU时间,操作系统以轮换方式向线程提供时间片,这就给人一种假象,好象这些线程都在同时运行。由此可见,如果两个非常活跃的线程为了抢夺对CPU的控制权,在线程切换时会消耗很多的CPU资源,反而会降低系统的性能。这一点在多线程编程时应该注意。

多线程的Java实现

JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。

继承Thread类与实现Runnable接口实现多线程

因为java是单继承的,继承了Thread类后就不能继承别的类,而实现了Runnable接口后依然可以继承其它类。因此这两种方法要根据情况选择。
下面是实现代码

public class Main{
public static void main(String[] args){
//生成继承自Thread类的自定义类的实例
Thread myThread1 = new MyThread();
//启动线程
myThread.start();
//生成实现Runnable接口的自定义类的实例
Runnable myRunnable = new MyRunnable();
Thread myThread2 = new Thread(myRunnable);
//启动线程
myThread2.start();
for(int i = 0; i < 50; i++){
System.out.println("Main-->" + i);
}
}
/**
*继承Thread类实现多线程
*/

class MyThread extends Thread{
public void run(){
for(int i = 0; i < 50; i++){
System.out.println("MyThread-->" + i);
}
}
}
/**
*实现Runnable接口
*/

class MyRunnable implements Runnable{
public void run(){
for(int i = 0; i < 50; i++){
System.out.println("MyRunnable-->" + i);
}
}
}
}

事实上,当传入一个Runnable target参数给Thread后,Thread的run()方法就会调用target.run(),参考JDK源代码:

public void run() {
  if (target != null) {
   target.run();
  }
}

参考资料
java线程概念:
http://blog.csdn.net/douglax/archive/2007/03/17/1532258.aspx
http://www.51ibm.com/thread-182849-1-1.html
java线程实现方式:
http://www.cnblogs.com/yezhenhan/archive/2012/01/09/2317636.html
java多线程运行效率
http://blog.csdn.net/cxn945/article/details/50903880
java Executor模式分析
http://www.iteye.com/topic/366591
java线程池分析
http://geek.csdn.net/news/detail/124863
java Callable&Future类分析
http://blog.csdn.net/vking_wang/article/details/9470499