专题学习(多线程)

1、线程的暂时停止

sleep方法的调用被放在try-catch里面,这是因为sleep方法可能会抛出一个称为InterruptedException的异常。
InterruptedException是用来取消线程处理时的异常。
“半路唤醒”被Thread sleep暂停的线程,则可利用interrupt方法

2、Synchronized实例方法和Synchronized阻挡

synchronized void method(){}

void method(){
        synchronized(this){}
}

synchronized方法是使用this锁去做线程的共享互斥。
this 指的是当前对象实例本身,所以,所有使用 synchronized(this) 方式的方法都共享同一把锁。

3、Synchronized类方法和Synchronized阻挡

synchronized类方法有限制同时只能让一个线程执行。这部分和synchronized实例方法一样,
但是两者是有不同的。
Class Something{
    static synchronized voidmethod(){}
    static synchronized void method2() {
     }
}

Class Something{
    static void method(){
       synchronized(Something.class){}
    }
 
}
synchronized的类方法是使用该类的类对象的锁去做线程的共享互斥。
Something.class是对应Something类的java.lang.Class类的实例。

//这里synchronized关键字拿到的锁是对象object的锁,
// 所有需要这个对象的锁的方法都不能同时执行。这是最常用的高并发场景下要锁住某个方法所用的操作。
// 锁住同一个变量的方法块共享同一把锁。
public class Something {
    private Object lock1 = new Object();
    private Object lock2 = new Object();
    private Object lock3 = new Object();

    public void lockMethod1() {
        synchronized (lock1) {
        }
    }

    public void lockMethod2() {
        synchronized (lock1) {
        }
    }

    public void lockMethod3() {
        synchronized (lock2) {
        }
    }

    // this
    public synchronized void method1() {
    }

    public void method2() {
        synchronized (this) {
        }
        // ...
    }

    // Something.class
    public static synchronized void staticMethod1() {
    }

    public static synchronized void staticMethod2() {
        synchronized (Something.class) {
        }
    }
}

4、wait set—线程的休息室

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7SqsDkLO-1663913736266)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/10f209b4-427a-45d3-9c01-af3893b9083c/Untitled.png)]

每个实例都有个线程的休息室wait set。
Wait方法——把线程放入wait set
使用wait方法时,线程便进入wait set,假设现在已经执行如下语句:obj.wait();
则目前的线程停止执行,进入实例obj的的wait set.这个操作成为:线程在obj上wait().(这个obj不是线程而是对象)
如果实例方法还有如下的语句时:wait();
则其意义同:this.wait();
故执行wait的线程就会进入this的wait set.此时就变成了在this上wait.
如欲执行wait()方法,线程需获取锁定(这是规则)。但是当线程进入wait set时,已经释放了该实例的锁定。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MGFFedps-1663913736268)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/f0f26fbd-3943-4246-95f9-0c666f454d03/Untitled.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z9R5lypV-1663913736269)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/96de494f-b01c-4b0f-9a4c-32063adf0ebe/Untitled.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QtOzLijO-1663913736271)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ce28ccbc-d014-4381-9c62-7348c4298d65/Untitled.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RGyS2Y4w-1663913736273)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/71dc6e1f-9f88-4d48-ba24-c8ceca88dd8f/Untitled.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lpE8GhdO-1663913736274)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/7210feb9-548d-4bf7-a72e-f5cf65da1ed6/Untitled.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jkc31Je3-1663913736275)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/2ba9dd49-6412-4ca1-9ead-debb18372da5/Untitled.png)]

Notify后的线程
    被notify唤醒的线程不是在notify后立即执行,因为在notify的那一刻,执行notify 的线程还握着锁定不放,所以其他线程无法获取该实例的锁定。
Notify如何选择线程
       假设执行notify方法时,wait set里面正在执行的线程不止一个。规格并没有注明此时该选择哪一个线程。究竟是选择等待线程里面的第一个,随机选择或是另以其他方式选择,则以java处理系统而异。  
notifyAll()方法——从wait set 拿出所有线程
使用notifyAll(通知全体)方法时,会将所有在waitset苦等的线程都拿出来。
obj.notifyAll()则会唤醒所有留在实例obj的wait set里的线程。
而notifyAll();则其意义同this.notifyAll();故这个语句所在方法的实例(this)的wait set里的线程会全部放出来。
跟wait方法和notify方法一样,线程必须要获取要调用实例的锁定,才能调用notifyAll方法。
被唤醒的线程便开始去获取刚才wait时释放掉的锁定,那么现在这个锁定现在是在谁的手中呢?没错,锁定就是在刚才执行notifyAll方法的程序手里,因此即使所有线程都退出了wait set,但他们仍然在去获得锁定的状态下,还是有阻挡。要等到刚才执行notifyAll方法的线程释放出锁定后,其中一名幸运儿才会实际执行。
要是没有锁定呢
   若没有锁定的线程去调用wait,notify或notifyAll时,便会抛出异常java.lang.IllegalMonitorStateException.
调用notify方法还是notifyAll方法
   Notify方法和notifyAll方法两者非常相似,到底该用哪一个?老实说,这个选择有点难。选择notify的话,因为要唤醒的线程比较少,程序处理速度当然要比notifyAll略胜一筹。但是选择notify时,若这部分程序处理的不好,可能会有程序挂掉的危险性,一般说来,选择notifyAll所写出来的程序代码要比选择notify可靠。除非你能确定程序员对程序代码的意义和能力限度一清二楚,否则选择notifyAll应该比较稳扎稳打

wait,notify,notifyAll是Object类的方法
obj.wait()是把现在的线程放到obj的wait set
obj.notify()是从obj的wait set里唤醒一个线程
obj.notifyAll()是唤醒所有在obj的wait set里的线程
换句话说,把wait、notify、notifyAll三者均解释为对实例对象的wait set的操作,会比说他们是对线程的操作更贴切,由于所有实例都会有wait set,所以wait、notify、notifyAll才会是Object类的方法。
虽然三者不是Thread类固有的方法,不过,因为Object类是Java所有类的祖先类,所以wait、notify、notifyAll也是Thread的方法。

5、线程的基本概念、线程的基本状态以及状态之间的关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DnqW8EtJ-1663913736276)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/9595a991-d82a-43d7-ab91-a1fbf7b0e30c/Untitled.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bYFSyR4t-1663913736279)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/59fce670-d85d-4d69-8040-7eeb91fb3dbd/Untitled.png)]

1. 新建( new ):新创建了一个线程对象。
2. 可运行( runnable ):线程对象创建后,其他线程(比如 main 线程)调用了该对象 的 start ()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获 取 cpu 的使用权 。
3. 运行( running ):可运行状态( runnable )的线程获得了 cpu 时间片( timeslice ) ,执行程序代码。
4. 阻塞( block ):阻塞状态是指线程因为某种原因放弃了 cpu 使用权,也即让出了 cpu timeslice ,暂时停止运行。直到线程进入可运行( runnable )状态,才有 机会再次获得 cpu timeslice 转到运行( running )状态。阻塞的情况分三种:
Blocked(堵塞)状态:
同步锁;调用了sleep()join()方法进入Sleeping状态;执行wait()方法进入Waiting状态,等待其他线程notify通知唤醒)(). 等待阻塞:运行( running )的线程执行 o . wait ()方法, JVM 会把该线程放 入等待队列( waitting queue )中。
(). 同步阻塞:运行( running )的线程在获取对象的同步锁时(synchronized),若该同步锁被别的线程占用,则 JVM 会把该线程放入锁池( lock pool )中。
(). 其他阻塞: 运行( running )的线程执行 Thread . sleep ( long ms )或 t . join ()方法,或者发出了 I / O 请求时, JVM 会把该线程置为阻塞状态。当 sleep ()状态超时、 join ()等待线程终止或者超时、或者 I / O 处理完毕时,线程重新转入可运行( runnable )状态。
5. 死亡( dead ):线程 run ()、 main () 方法执行结束,或者因异常退出了 run ()方法,则该线程结束生命周期。死亡的线程不可再次复生。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hQaC4cDu-1663913736281)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/87daa383-f240-4ef0-ba75-3bd67ebae384/Untitled.png)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值