Java多线程:5.Thread类和Object类的重要方法

一、重要方法概览

方法名 说明
Thread sleep() 让线程等待
join() 等待其他线程执行完毕
yield() 放弃已经获取到的CPU资源
currentThread() 获取当前执行线程的引用
start()、run() 启动线程
interrtupt() 中断线程
stop()、suspend()、resuem() 已废弃
Object wait()、notify()、notifyAll() 让线程暂时休息和唤醒

二、Object类中的wait()、notify()、notifyAll()

1.作用
  • 阻塞阶段
    执行wait()后,线程进入阻塞状态,wait()需要在synchronized的方法中使用。
  • 唤醒阶段
    notify()会唤醒某个正在等待锁的线程,如果有多个线程都在等待锁,则会选取其中任意一个唤醒。需要在synchronized的方法中使用
    notifyAll()会把所有正在等待的线程全部唤醒,最终哪个线程能获得锁,由操作系统决定。
  • 遇到中断
    线程在阻塞状态,如果被中断了,则该线程会抛出中断异常并释放锁。
2.wait()和notify()的演示
/**
 * Object类中的wait()、notify()的基本用法
 */
public class ThreadWaitNotify {

    public static Object object = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(new DoWork1());
        Thread thread2 = new Thread(new DoWork2());

        thread1.start();
        Thread.sleep(1000);
        thread2.start();
    }
}

class DoWork1 implements Runnable{
    @Override
    public void run() {
        synchronized (ThreadWaitNotify.object){
            System.out.println("线程1开始执行");
            try {
                // 释放锁,阻塞
                ThreadWaitNotify.object.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("线程1重新获得锁");
        }
    }
}

class DoWork2 implements Runnable{
    @Override
    public void run() {
        synchronized (ThreadWaitNotify.object){
            ThreadWaitNotify.object.notify();
            System.out.println("线程2调用notify()");
        }
    }
}

在这里插入图片描述
线程1中执行了wait()语句后即线程1进入等待状态,并且释放掉了锁,否则线程2无法进入synchronized的代码块。

3.notify()和notifyAll()的演示
/**
 * Object类中的notify()、notifyAll()的基本用法
 * 线程1、线程2阻塞,线程3负责唤醒他们
 */
public class ThreadWaitNotify {

    public static Object resource = new Object();

    public static void main(String[] args) throws InterruptedException {
        DoWork1 doWork = new DoWork1();
        DoWork3 doWork3 = new DoWork3();

        Thread thread1 = new Thread(doWork);
        Thread thread2 = new Thread(doWork);
        Thread thread3 = new Thread(doWork3);

        thread1.start();
        thread2.start();

        Thread.sleep(100);
        thread3.start();
    }
}

class DoWork1 implements Runnable{
    @Override
    public void run() {
        synchronized (ThreadWaitNotify.resource){
            System.out.println("线程["+Thread.currentThread().getName()+"]获得锁开始执行");
            try {
                // 释放锁,阻塞
                System.out.println("线程["+Thread.currentThread().getName()+"]wait阻塞释放锁");
                ThreadWaitNotify.resource.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("线程["+Thread.currentThread().getName()+"]重新获得锁");
        }
    }
}

class DoWork3 implements Runnable{
    @Override
    public void run() {
        synchronized (ThreadWaitNotify.resource){
            ThreadWaitNotify.resource.notifyAll();
            System.out.println("线程["+Thread.currentThread().getName()+"]调用notify()");
        }
    }
}

在这里插入图片描述
如果把notifyAll()换成notify()呢?
线程0和线程1都在阻塞,而线程2只选择唤醒一个,那么应该剩余一个线程永远在阻塞了。

class DoWork3 implements Runnable{
    @Override
    public void run() {
        synchronized (ThreadWaitNotify.resource){
            ThreadWaitNotify.resource.notify();
            System.out.println("线程["+Thread.currentThread().getName()+"]调用notify()唤醒一个线程");
        }
    }
}

在这里插入图片描述

4.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章