多线程——死锁、同步、通信

多线程之常用方法

start();
//启动当前线程,调用当前线程的run();
run();
//通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中;
currentThread();
//静态方法,返回执行当前代码的线程。
getName();
//获取当前线程的名字
setName();
//设置当前线程的名字
yield();
//释放当前cpu的执行权
join();
//在线程a中调用线程b的join(),此时线程a就进入阻塞状态,直到线程b完全执行结束。
sleep(long time);
//让当前线程"睡眠"指定的time毫秒

多线程之同步

​ 在Java中,我们通过同步机制来解决线程的安全问题。

方法一:同步代码块

synchronized(同步监视器){
  	//需要被同步的代码
  
}

说明:

  1. 操作共享数据的代码,即为需要被同步的代码。

  2. 共享数据:多个线程共同操作的变量。

  3. 同步监视器,俗称:锁。任何一个类的对象,都可以充当锁。

    要求:多个线程必须要共用一把锁。
  • 同步的方式,解决了线程的安全问题。(优点)
  • 操作同步代码时,只能有一个线程参与,其他线程等待。(局限性)

方法二:同步方法

public class synchronized void show(){
  	//需要被同步的代码
  
}

说明:

  1. 同步方法仍然涉及到同步监视器,只是不需要我们显示声明。

  2. 非静态的同步方法,它的同步监视器是:this

    静态的同步方法,它的同步监视器是:当前类本身

死锁


​ 不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁。

说明:

  1. 出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于阻塞状态,无法继续。
  2. 我们使用同步时,要避免出现死锁。
  • synchronized与lock的异同

相同:二者都可以解决线程安全问题

不同:synchronized机制在执行完相应的同步代码后,自动释放同步监视器。

​ lock需要手动地启动同步 lock() ,同时结束同步也可以手动实现。

优先使用顺序:lock -> synchronized(){} -> class synchronized

多线程之通信

多线程通信案例:交替打印

针对 synchronized涉及到三个方法:

wait();
//一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器。
notify();
//一旦执行此方法,就会唤醒被wait的一个线程,如果有多个线程被wait,就优先唤醒优先级高的。
norifyAll();
//一旦执行此方法,就会唤醒所有被wait的线程。

Q:sleep和wait的异同?

A:

  • 相同点 一旦执行该方法,当前线程都将进入阻塞状态。

  • 不同点 1.两个方法声明的位置。(Thread/Object)

​ 2.使用场景。(anywhere/synchronized)

​ 3.同时出现时,sleep不会释放同步监视器,wait会。

posted @ 2022-01-29 01:35  ice_yolo  阅读(40)  评论(0)    收藏  举报