线程:操作系统的最小调度单位(轻量级进程)。在一个进程中可以有多个线程,这些线程都拥有自己的计数器、堆栈、局部变量等属性,并且能够访问共享的内存变量。处理器在这些线程上高速切换,使得我们觉得是同时执行的。
调度线程:操作系统会分出一个个时间片,线程会分配到若干时间片,当线程的时间片用完了就会发生线程调度,并等待着下一次分配。线程优先级就是决定线程或多或少分配一些处理器资源的线程属性。
public class Priority {
private static volatile boolean notStart = true;
private static volatile boolean notEnd = true;
public static void main(String[] args) throws InterruptedException {
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();
}
notStart = false;
TimeUnit.SECONDS.sleep(10);
notEnd = false;
for (Job job : jobs) {
System.out.println("job priority:::" + 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++;
}
}
}
}
job priority:::1.count:::::13571435
job priority:::1.count:::::13553446
job priority:::1.count:::::13747551
job priority:::1.count:::::12980625
job priority:::1.count:::::13890939
job priority:::10.count:::::14269826
job priority:::10.count:::::14491022
job priority:::10.count:::::14462749
job priority:::10.count:::::14366369
job priority:::10.count:::::14404920
从结果可以看出,优先级1和优先级10计数结果差距不大。说明多线程的正确性不能依赖优先级的高低
public class ThreadState {
public static void main(String[] args) {
new Thread(new TimeWaiting(), "TIME WAITING").start();
new Thread(new Waiting(), "waiting").start();
//使用两个blockde线程,一个获取成功,一个阻塞
new Thread(new Blocked(), "BLOCKED---1").start();
new Thread(new Blocked(), "blocked --2").start();
}
//该线程不断进行睡眠
static class TimeWaiting implements Runnable {
@Override
public void run() {
while (true) {
SleepUtils.second(100);
}
}
}
//该线程在waiting.class实例上等待
static class Waiting implements Runnable {
@Override
public void run() {
while (true) {
synchronized (Waiting.class) {
try {
Waiting.class.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
//该线程在Blocked.class实例上加锁,不会释放锁
static class Blocked implements Runnable {
@Override
public void run() {
synchronized (Blocked.class) {
while (true) {
SleepUtils.second(100);
}
}
}
}
}
分析结果可以看出
9024 Jps
13172 Launcher
4068 ThreadState
1772
查看进程jstack4068:
"blocked --2" #15 prio=5 os_prio=0 tid=0x0000000020f92800 nid=0x3398 waiting for monitor entry [0x000000002205f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java并发编程的艺术.one.ThreadState$Blocked.run(ThreadState.java:46)
- waiting to lock <0x000000076b62b938> (a java.lang.Class for java并发编程的艺术.one.ThreadState$Blocked)
at java.lang.Thread.run(Thread.java:748)
可以看出Block–2,线程阻塞在获取BLOCKED示例的锁上
"BLOCKED---1" #14 prio=5 os_prio=0 tid=0x0000000020fb6000 nid=0x2740 waiting on condition [0x0000000021f5f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at java并发编程的艺术.one.SleepUtils.second(SleepUtils.java:8)
at java并发编程的艺术.one.ThreadState$Blocked.run(ThreadState.java:46)
- locked <0x000000076b62b938> (a java.lang.Class for java并发编程的艺术.one.ThreadState$Blocked)
at java.lang.Thread.run(Thread.java:748)
block-1,获取到了Blocked.class实例的锁
"waiting" #13 prio=5 os_prio=0 tid=0x0000000020fb4000 nid=0x353c in Object.wait() [0x0000000021e5e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076b628d40> (a java.lang.Class for java并发编程的???术.one.ThreadState$Waiting)
at java.lang.Object.wait(Object.java:502)
at java并发编程的艺术.one.ThreadState$Waiting.run(ThreadState.java:31)
- locked <0x000000076b628d40> (a java.lang.Class for java并发编程的艺术.one.ThreadState$Waiting)
at java.lang.Thread.run(Thread.java:748)
Waiting线程获取到了waiting实例上的锁
"TIME WAITING" #12 prio=5 os_prio=0 tid=0x0000000020f92000 nid=0x27c waiting on condition [0x0000000021d5f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at java并发编程的艺术.one.SleepUtils.second(SleepUtils.java:8)
at java并发编程的艺术.one.ThreadState$TimeWaiting.run(ThreadState.java:19)
at java.lang.Thread.run(Thread.java:748)
timewaiting处于超时等待
从上图看出:线程创建后,调用start开始运行,当执行wait后,进入等待状态。进入等待的线程需要其他线程的通知才可以返回到运行状态,超时等待是在等待的基础上加了超时时间设置,超时时间到达,自动返回到运行状态。调用同步方法时,没有获取到锁的时,进入阻塞状态。执行run()方法后进入到终止状态。
阻塞状态是指线程阻塞在进入Synchronized方法(获取锁)时的状态。
单只阻塞在concurrent包中Lock接口下的却是等待状态,因为Lock接口对于阻塞都实现了LockSupport类中的方法
public class Interrupted {
public static void main(String[] args) throws InterruptedException {
//sleep尝试不断睡眠
Thread sleep = new Thread(new Sleep(), "SLEEP");
sleep.setDaemon(true);
//sleep不停运行
Thread busy = new Thread(new busy(), "busy");
busy.setDaemon(true);
sleep.start();
busy.start();
//休眠5秒
TimeUnit.SECONDS.sleep(5);
sleep.interrupt();
busy.interrupt();
System.out.println("sleep ---" + sleep.isInterrupted());
System.out.println("busy ---" + busy.isInterrupted());
SleepUtils.second(2);
}
static class Sleep implements Runnable {
@Override
public void run() {
while (true) {
SleepUtils.second(100);
}
}
}
sleep —false
busy —true