现代操作系统调度的最小单元是线程,也叫轻量级进程(light Weight Process), 在一个进程里可以创建多个线程,这些线程都拥有各自的计数器、堆栈和局部变量等属性。
并能访问线程的共享内存变量 ThreadLocal 。 处理器在这些线程上高速切换,让使用者感觉到这些线程在同时执行。这就是我们常说的多线程执行。
下面给出一段从main 方法开始,执行监控多线程的一段代码:
@Test
public void test1() {
// 获取Java线程管理 MXBean
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
// 不需要同步的 monitor 和 synchronizer 信息, 仅获取线程堆栈信息
ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false,false);
// 遍历线程信息,仅打印线程ID 和 线程名称信息
for(ThreadInfo threadInfo : threadInfos) {
System.out.println("[" + threadInfo.getThreadId() + "]" + threadInfo.getThreadName());
}
}
输出信息如下:
[10]Monitor Ctrl-Break // 监控中断
[5]Attach Listener // 绑定监听器
[4]Signal Dispatcher // 分发处理发送给JVM信号的线程
[3]Finalizer // 调用对象finalize方法的线程
[2]Reference Handler // 清除Reference的线程
[1]main // main 线程, 用户程序入口
看以看到main 程序中,拥有其他多个其他的线程同时在执行。
使用多线程主要有一下几个原因:
(1) 更多的处理器核心
(2) 更加快的响应时间
(3)更好的编程模型
线程的优先级
现代的操作系统基本采用时分的形式来调度运行的线程,操作系统会分出一个个时间片,线程会分配到若干时间片,当线程的时间片用完了就会发生线程调度,并等待着下次分配。线程优先级就是决定线程需要多或少分配一些处理器资源的线程属性。
在java线程中 ,优先级是通过整形成员变量 prority 来控制有先级,优先级的范围从 1~10 , 线程构建的时候可以通过setProprity(int x)来设置,默认优先级是5. 数值越高分配的时间越多。注意 : 设置线程优先级时,针对频繁阻塞的I/O 操作,线程需要较高的优先级,而偏重计算的线程则设置较低的优先级。当然在不同的JVM
和操作系统上,线程的优先级可能存在差异,或者不会起作用。
public class ProprityTest {
// 保证get set 的可见性
private static volatile boolean notStart = true;
private static volatile boolean notEnd = true;
@Test
public static void test1() throws InterruptedException {
List<Job> jobs = new ArrayList<Job>();
for (int i = 0; i < 10; i++) {
int pripority = i < 5 ? Thread.MIN_PRIORITY : Thread.MAX_PRIORITY;
Job job = new Job(pripority);
jobs.add(job);
Thread thread = new Thread(job, "Thread" + i);
thread.setPriority(pripority);
thread.start();
}
notStart = false;
TimeUnit.SECONDS.sleep(10);
notEnd = false;
for(Job job : jobs) {
System.out.println("Job Proprity : " + job.priority + ", Count : " + job.jobCount );
}
}
/**
* 工作线程。
*/
static class Job implements Runnable {
private int priority;
private long jobCount;
public Job(int priority) {
this.priority = priority;
}
@Override
public void run() {
while (notStart) {
Thread.yield();
}
while (notEnd) {
Thread.yield();
jobCount++;
}
}
}
}
java 线程在运行的生命周期中可能处于下面所示的6种不同的状态,在给定的一个时刻,线程只能处于其中的一种状态。
状态名称 | 说明 |
---|---|
NEW | 初始状态,线程被构建,但是还没有调用start()方法。 |
RUNNABLE | 运行状态,Java线程将操作系统中的就绪和运行两种状态笼统地称作“运行中” |
BLOCKED | 阻塞状态,表示线程阻塞于锁 |
WAITING | 等待状态,表示线程进入等待状态,进入该状态表示当前线程需要等待其他线程做出一些特定动作(通知或中断) |
TIME_WAITING | 超时等a待状态 |
TERMINATED | 终止状态,表示当前线程已经执行完毕。 |