线程调度
1、线程状态
线程是cpu任务调度的最小执行单位,每个线程拥有自己独立的程序计数器、虚拟机栈、本地方法栈
线程状态:创建、就绪、运行、阻塞、死亡
2、线程状态切换
| 方法 | 作用 | 区别 |
|---|---|---|
| start | 启动线程,由虚拟机自动调度执行run()方法 | 线程处于就绪状态 |
| run | 线程逻辑代码块处理,JVM调度执行 | 线程处于运行状态 |
| sleep | 让当前正在执行的线程休眠(暂停执行) | 不释放锁 |
| wait | 使得当前线程等待 | 释放同步锁 |
| notify | 唤醒在此对象监视器上等待的单个线程 | 唤醒单个线程 |
| notifyAll | 唤醒在此对象监视器上等待的所有线程 | 唤醒多个线程 |
| yiled | 停止当前线程,让同等优先权的线程运行 | 用Thread类调用 |
| join | 使当前线程停下来等待,直至另一个调用join方法的线程终止 | 用线程对象调用 |
3、阻塞唤醒过程
阻塞:
这三个方法的调用都会使当前线程阻塞。该线程将会被放置到对该Object的请求等待队列中,然后让出当前对Object所拥有的所有的同步请求。线程会一直暂停所有线程调度,直到下面其中一种情况发生:
① 其他线程调用了该Object的notify方法,而该线程刚好是那个被唤醒的线程;
② 其他线程调用了该Object的notifyAll方法;
唤醒:
线程将会从等待队列中移除,重新成为可调度线程。它会与其他线程以常规的方式竞争对象同步请求。一旦它重新获得对象的同步请求,所有之前的请求状态都会恢复,也就是线程调用wait的地方的状态。线程将会在之前调用wait的地方继续运行下去。
为什么要出现在同步代码块中:
由于wait()属于Object方法,调用之后会强制释放当前对象锁,所以在wait() 调用时必须拿到当前对象的监视器monitor对象。因此,wait()方法在同步方法/代码块中调用。
4、wait和sleep区别
- wait 方法必须在 synchronized 保护的代码中使用,而 sleep 方法并没有这个要求。
- wait 方法会主动释放 monitor 锁,在同步代码中执行 sleep 方法时,并不会释放 monitor 锁。
- wait 方法意味着永久等待,直到被中断或被唤醒才能恢复,不会主动恢复,sleep 方法中会定义一个时间,时间到期后会主动恢复。
- wait/notify 是 Object 类的方法,而 sleep 是 Thread 类的方法。
5、创建线程方式
实现 Runnable 接口(优先使用)
public class RunnableThread implements Runnable {
@Override
public void run() {System.out.println('用实现Runnable接口实现线程');}
}
实现Callable接口(有返回值可抛出异常)
class CallableTask implements Callable<Integer> {
@Override
public Integer call() throws Exception { return new Random().nextInt();}
}
继承Thread类(java不支持多继承)
public class ExtendsThread extends Thread {
@Override
public void run() {System.out.println('用Thread类实现线程');}
}
使用线程池(底层都是实现run方法)
static class DefaultThreadFactory implements ThreadFactory {
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
namePrefix = "pool-" + poolNumber.getAndIncrement() +"-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,namePrefix + threadNumber.getAndIncrement(),0);
if (t.isDaemon()) t.setDaemon(false); //是否守护线程
if (t.getPriority() != Thread.NORM_PRIORITY) t.setPriority(Thread.NORM_PRIORITY); //线程优先级
return t;
}
}
- [ 萱儿AXW ]