线程
通过使用线程,可以把操作系统进程的资源分配和执行调度分开,各个线程既可以共享进程资源(内存地址、文件I/O等),又可以独立调度(线程是CPU调度的基本单位)。
主流操作系统(Windows,Linux)都提供了线程的实现,Java则提供了在不同硬件和操作系统下对线程的统一处理,Thread类则是Java中线程的实现。
Java线程使用操作系统的内核线程实现,内核线程(KLT)是直接由操作系统内核支持的线程,这种线程由内核来完成线程切换,内核通过操纵调度器对线程进行调度,并负责将线程的任务映射到各个处理器上。
程序一般通过使用内核线程的高级接口——轻量级进程(Light Weight Process,LWP),也就是我们通常意义上的线程。每个LWP都由一个内核线程支持。也就是说任何时候使用Java代码创建线程,调用Thread.start()的时候,都是通过LWP接口创建了KLT内核线程,然后通过OS的Thread Schedule对内核线程进行调度分配CPU。
内核线程的优点:
(1)每一个内核线程都是独立的轻量级进程,一个线程的阻塞不会影响整个进程的工作。
内核线程的缺点:
(1)由于是基于内核线程实现,各种线程的操作,如创建、析构、中断、休眠和同步,都需要系统调度(频繁从用户态切换进内核态),而系统调度的代价相对较高;
(2)占用内核资源,同时轻量级进程的数量有限。
Thread线程运行在Java Virtual Machine中,要理解Java中线程的运行方式,得先了解Java内存模型。Java虚拟机规范中定义了一种Java内存模型(Java Memory Model)来屏蔽各种硬件和操作系统的内存访问差异,以实现Java程序在各种平台下都能达到一致的内存访问效果(一次编译,随处运行得以实现的基础)。
主内存与工作内存:
Java内存模型规定了所有的变量都存储在主内存中。所有的线程都有自己的内存工作内存,工作内存中保存了被该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作(读取、赋值)都必须在工作内存中执行,而不能直接读写主内存中的变量。
线程之间也无法读写各自的工作内存。关系图:
Thread类构造方法:
1、Thread();
2、Thread(String name);
3、Thread(Runable r);
4、Thread(Runable r,String name);
示例:
Public class Test{
Public static void main(String[] args){
MyRunnable run=new MyRunnable();
Thread thread3=new Thread(run);
Thread thread4=new Thread(run, "MyThread");
thread3.start();
thread4.start();
}
}
Thread中的常用方法:
start();//启动线程
getId();//获得线程ID
getName();//获得线程名字
getPriority();//获得优先权
isAlive();//判断线程是否活动
isDaemon();//判断是否守护线程
getState();//获得线程状态
sleep(long mill);//休眠线程
join();//等待线程结束
yield();//放弃cpu使用权利
interrupt();//中断线程
currentThread();//获得正在执行的线程对象
wait();//设置当前想成在该对象上等待
notify();//随机唤醒其中一个线程
notifyall();//唤醒所有线程
join();//等待线程,其本质是让调用线程wait在当前线程对象实例上
yield();//使当前线程让出CPU