多线程篇复习: 上篇

221 阅读3分钟

线程调度

1、线程状态

线程是cpu任务调度的最小执行单位,每个线程拥有自己独立的程序计数器、虚拟机栈、本地方法栈

线程状态:创建、就绪、运行、阻塞、死亡

img

2、线程状态切换

方法作用区别
start启动线程,由虚拟机自动调度执行run()方法线程处于就绪状态
run线程逻辑代码块处理,JVM调度执行线程处于运行状态
sleep让当前正在执行的线程休眠(暂停执行)不释放锁
wait使得当前线程等待释放同步锁
notify唤醒在此对象监视器上等待的单个线程唤醒单个线程
notifyAll唤醒在此对象监视器上等待的所有线程唤醒多个线程
yiled停止当前线程,让同等优先权的线程运行用Thread类调用
join使当前线程停下来等待,直至另一个调用join方法的线程终止用线程对象调用

img

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 ]