2-Lock

作者: 鹏程1995 | 来源:发表于2020-02-04 17:53 被阅读0次

类介绍

类定位

定义了Lock的常用的方法。

类注意事项

lock的常用注意事项在上一章中已经写清楚了。此处主要关注源码都有哪些接口。

引用别人博客的一张图:

1.png

源码解析

void lock()

  1. 目的:获得锁
  2. 特性:可阻塞方法,不会被中断

void lockInterruptibly()

  1. 目的:获得锁
  2. 特性:可阻塞方法,可中断,会抛中断异常

boolean tryLock()

  1. 目的:获得锁
  2. 特性:非阻塞方法,即时返回

boolean tryLock(long time, TimeUnit unit)

  1. 目的:获得锁
  2. 特性:阻塞方法,最多阻塞相应的时间

void unlock()

  1. 目的:解除锁占用
  2. 特性:如未占用此锁,调用解除占用会抛出异常

Condition newCondition()

返回一个Condition对象,具体的作用在阅读Condition后再补全。

拓展

java线程状态及之间的转化

2.jpg

直接盗用别人的图。这个是我找的比较简洁的图。主要是线程状态的展示。

java常见的一些线程操作函数介绍

Thread.sleep()

方法介绍

Thread.sleep()是一个静态方法,可使此线程阻塞一定时间。

方法重点提要

  • 前置条件:
    • 线程运行状态(线程占据cpu时间片执行)
  • 执行的操作注意事项:
    • 如果线程当前占有锁,此操作不会放弃锁
  • 后置条件:
    • 放弃cpu时间片,转入阻塞状态
    • 时间到期后重新转入就绪状态

Thread.yield()

方法介绍

Thread.yield()是一个静态方法,可使此线程直接结束此次时间片。

方法重点提要

  • 前置条件:
    • 线程运行状态(线程占据cpu时间片执行)
  • 执行的操作注意事项:
    • 如果线程当前占有锁,此操作不会放弃锁
  • 后置条件:
    • 放弃cpu时间片,转入就绪状态,等待系统线程调度

示例代码:

package com.gateway.learn.java8.learnCollector;

/**
 * @author lipengcheng Created date 2018-11-13 11:09
 * @description:
 */
public class Main implements Runnable {

    String showTag;

    Object test;

    public static void main(String args[]) {
        Object x = new Object();

        Main a = new Main();
        a.setShowTag("a");
        a.setTest(x);
        Thread aa = new Thread(a);

        Main b = new Main();
        b.setShowTag("b");
        b.setTest(x);
        Thread bb = new Thread(b);

        Main c = new Main();
        c.setShowTag("c");
        c.setTest(x);
        Thread cc = new Thread(c);

        aa.start();
        bb.start();
        cc.start();
    }

    public Object getTest() {
        return test;
    }

    public void setTest(Object test) {
        this.test = test;
    }

    public String getShowTag() {
        return showTag;
    }

    public void setShowTag(String showTag) {
        this.showTag = showTag;
    }

    @Override
    public void run() {
        try {
            synchronized (this.test) {
                System.out.println(this.showTag + " start");

                Thread.sleep(1000);

                System.out.println(this.showTag + " end");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Thread.join()

方法介绍

Thread.join()是一个实例方法,在线程A中调用B.join(),线程A会进入阻塞状态,等线程B结束后重新回到就绪状态。

方法重点提要

  • 前置条件:
    • A线程处于运行状态(线程占据cpu时间片执行)
  • 执行的操作注意事项:
    • 不释放已经获得的锁
  • 后置条件:(调用B.join()后)
    • 转入阻塞状态,等待B线程结束后重新回到就绪状态。

Thread.interrupt()

方法介绍

Thread.interrupt()是实例方法,在线程A中调用B.interrupt(),作用是通知B线程应该中断了而非A线程中断B线程。表现在如果是线程的阻塞状态,系统直接替你停止线程阻塞并抛出异常;如果是线程就绪/运行状态,需要你自己去检测中断标志位并进行响应(停止线程/阻塞等后续操作/不管,继续执行)

方法重点提要

情况一
  • 前置条件:
    • 线程处于阻塞状态
  • 执行的操作注意事项:
    • 会不会释放所有占有的锁,看抛出的异常是否会导致提前结束synchronized块或者程序员是否在处理异常时手动释放锁
  • 后置条件:
    • 线程结束阻塞状态
    • 抛出java.lang.InterruptedException异常

示例代码:

// 中断不会释放锁
public void run() {

    synchronized (this.test) {
        System.out.println(this.showTag + " start");
        try {
            Thread.sleep(1000);

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(this.showTag + " end");
    }

}


// 中断会释放锁
public void run() {
    try {
        synchronized (this.test) {
            System.out.println(this.showTag + " start");

            Thread.sleep(1000);

            System.out.println(this.showTag + " end");
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
情况二
  • 前置条件:
    • 线程处于运行/就绪状态【看cpu的调度时啥情况了】
  • 执行的操作注意事项:
    • 会有何种动作完全看编程人员的操作了
  • 后置条件:
    • 会有何种动作完全看编程人员的操作了

Thread.isInterrupted(boolean)

方法介绍

Thread.isInterrupted(boolean)是一个实例方法,用于确定此线程是否已经被其他线程打上中断标签

  • 传入值true,返回结果后如果是true(已经被其他线程提示中断),则将中断标志置为false
  • 传入值false,直接返回结果,不做修改操作

方法重点提要

  • 前置条件:
    • A线程处于运行状态(线程占据cpu时间片执行)
  • 执行的操作注意事项:
    • 只是用于检验/检验加标记归位,不做其他操作
  • 后置条件:
    • 看编程人员的操作

Thread.interrupted()

方法介绍

等价于Thread.isInterrupted(true)

Object.wait()

方法介绍

Object.wait()是一个实例方法,调用后此线程放弃当前对象对应的锁,进入阻塞状态。直到被唤醒或者阻塞时间已到,然后重新参与锁的竞争。

方法重点提要

  • 前置条件:
    • 线程处于运行状态(线程占据cpu时间片执行)
  • 执行的操作注意事项:
    • 放弃已经占用的锁
  • 后置条件:
    • 线程放弃锁,并阻塞
    • 等待被唤醒/阻塞时间到达后重新参与锁的竞争

注意:重新参与锁的竞争,这句话有以下含义

  1. 参与竞争------->不一定会立刻获得锁,看系统怎么调度了
  2. 锁的失去--->之前对临界资源的更改都生效了
  3. 锁的重新获得----->临界资源都会更新到最新状态

Object.notify()

方法介绍

实例方法,调用A.notify()后唤醒一个A.wait()而阻塞的线程,并使其转到就绪状态,重新参与锁的竞争。

方法重点提要

  • 前置条件:
    • 本线程处于运行状态(线程占据cpu时间片执行)
  • 执行的操作注意事项:
  • 后置条件:
    • 本线程仍正常运行
    • 一个A.wait()而阻塞的线程被唤醒

Object.notifyAll()

方法介绍

实例方法,调用A.notifyall()后唤醒所有A.wait()而阻塞的线程,并使其转到就绪状态,重新参与锁的竞争。

方法重点提要

  • 前置条件:
    • 本线程处于运行状态(线程占据cpu时间片执行)
  • 执行的操作注意事项:
  • 后置条件:
    • 本线程仍正常运行
    • 所有A.wait()而阻塞的线程被唤醒

文献参考

java 线程操作函数

https://blog.csdn.net/fuyuwei2015/article/details/71790129

https://blog.csdn.net/qq_38663729/article/details/78068540

https://www.jianshu.com/p/ce681912857f

https://blog.csdn.net/xiangwanpeng/article/details/54972952

java 线程状态及转换关系

https://blog.csdn.net/huakai_sun/article/details/78287931

https://blog.csdn.net/pange1991/article/details/53860651

https://my.oschina.net/mingdongcheng/blog/139263

http://www.jiacheo.org/blog/338

https://www.cnblogs.com/barrywxx/p/4343069.html

相关文章

  • 2-Lock

    类介绍 类定位 定义了Lock的常用的方法。 类注意事项 lock的常用注意事项在上一章中已经写清楚了。此处主要关...

网友评论

      本文标题:2-Lock

      本文链接:https://www.haomeiwen.com/subject/lzfdxhtx.html