1.线程
线程:又称轻量级进程,是现代操作系统的最小调度单元。JAVA从诞生开始就明智的选择了内置对多线程的支持。
在一个进程中可以创建多个线程,这些线程拥有各自的计数器、堆栈和局部变量等特性,并且能够访问共享的内存变量。在JVM中,我们也可以了解到,程序计数器、虚拟机栈和本地方法栈都是线程私有的。
线程切换与进程切换相比,代价开销较小, 因此能够提高CPU效率。
关于进程与线程,推荐阅读阮一峰的网络日志
2.线程优先级
现代操作系统基本采用时分的形式调度运行的线程,线程分配得到的时间片的多少决定了线程使用处理器资源的多少,也对应了线程优先级这个概念。在JAVA线程中,通过一个int priority来控制优先级,范围为1-10,其中10最高,默认值为5。下面是源码(基于1.8)中关于priority的一些量和方法。
private int priority;
/**
* Changes the priority of this thread.
* <p>
* First the <code>checkAccess</code> method of this thread is called
* with no arguments. This may result in throwing a
* <code>SecurityException</code>.
* <p>
* Otherwise, the priority of this thread is set to the smaller of
* the specified <code>newPriority</code> and the maximum permitted
* priority of the thread's thread group.
*
* @param newPriority priority to set this thread to
* @exception IllegalArgumentException If the priority is not in the
* range <code>MIN_PRIORITY</code> to
* <code>MAX_PRIORITY</code>.
* @exception SecurityException if the current thread cannot modify
* this thread.
* @see #getPriority
* @see #checkAccess()
* @see #getThreadGroup()
* @see #MAX_PRIORITY
* @see #MIN_PRIORITY
* @see ThreadGroup#getMaxPriority()
*/
public final void setPriority(int newPriority) {
ThreadGroup g;
checkAccess();
if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
throw new IllegalArgumentException();
}
if((g = getThreadGroup()) != null) {
if (newPriority > g.getMaxPriority()) {
newPriority = g.getMaxPriority();
}
setPriority0(priority = newPriority);
}
}
/**
* Returns this thread's priority.
*
* @return this thread's priority.
* @see #setPriority
*/
public final int getPriority() {
return priority;
}
显然,对于需要较多CPU时间的线程需要设置较低的优先级,这样可以确保处理器不会被独占。
另外:
线程优先级不能作为程序正确性的依赖,因为操作系统可以完全不用理会JAVA线程对于优先级的设定。——->《JAVA并发编程基础》
下面是一个关于线程优先级的程序:
package com.xidian.sortthird;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class TestPriority
{
private static volatile boolean notStart=true;
private static volatile boolean notEnd=true;
public static void main(String[] args) throws Exception
{
List<Job> jobs = new ArrayList<>();
for(int i = 0;i<10;i++)
{
int priority = i<5?Thread.MIN_PRIORITY:Thread.MAX_PRIORITY;
Job job=new Job(priority);
jobs.add(job);
Thread thread=new Thread(job, "Thread:"+i);
thread.setPriority(priority);
thread.start();
}//使用这个循环启动了10个线程
notStart=false;
TimeUnit.SECONDS.sleep(10);//main线程沉睡10s,使得10个小线程执行结束
notEnd=false;
for(Job job:jobs)
{
System.out.println("JOB priority:"+job.priority+","+job.jobCount);
}
}
static class Job implements Runnable
{
private int priority;
private long jobCount;
public Job(int priority)
{
this.priority=priority;
}
public void run()
{
while(notStart)
{
Thread.yield();//这里确保main线程将10个小线程启动成功
}
while(notEnd)
{
Thread.yield();//这里让出CPU资源,使得10个线程自由竞争。
jobCount++;//记录竞争状态,反映线程的优先级。
}
}
}
}
下面是运行结果,不过这个结果有很大的迷惑性:
JOB priority:1,1099494
JOB priority:1,1097710
JOB priority:1,1099911
JOB priority:1,1100411
JOB priority:1,1099721
JOB priority:10,5208263
JOB priority:10,5198474
JOB priority:10,5213148
JOB priority:10,5184842
JOB priority:10,5172312
可以看出,的确是优先级高的得到的时间片较多,但是这个结果是具有迷惑性的,让我们看一下LINUX环境下的运行结果:
JOB priority:1,3075988
JOB priority:1,2899121
JOB priority:1,2843459
JOB priority:1,2780645
JOB priority:1,2910943
JOB priority:10,3243229
JOB priority:10,12090519
JOB priority:10,3027128
JOB priority:10,6275521
JOB priority:10,2995204
从上面这个结果可以看出,操作系统并没有理会我们设置的线程优先级。