IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> JUC(二): Synchronized和Lock接口 -> 正文阅读

[Java知识库]JUC(二): Synchronized和Lock接口

Lock接口

Synchronized

Synchronized关键词回顾

synchronied是Java中的关键字,是一个同步锁.他修饰的对象有以下几种:

  1. 修饰一个代码块,被修饰的代码块成为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
  2. 修饰一个方法,被修饰的方法成为同步方法,起作用的范围是整个方法,作用的对象是调用这个方法的对象;
    • 虽然可以使用synchronized来定义方法,但是synchronized并不属于方法定义的一部分,因此,synchronized关键字不能被继承.如果在父类中的某个方法是用了synchronized关键字,而在子类中覆盖了这个方法,在子类中的这个方法默认情况下并不是同步的,而必须现式地在子类的这个方法中加上synchronized关键字才可以.当然还可以在子类方法中调用父类中相应的方法,这样虽然子类中的方法不是同步的,当子类调用了父类的同步方法,因此,子类的方法也相当于是同步了
  3. 修饰一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
  4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象;

小例子:修饰一个方法

如果一个代码块被 synchronized 修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况:

  • 获取锁的线程执行完了该代码块,然后线程释放对锁的占有;

  • 线程执行发生异常,此时 JVM 会让线程自动释放锁。

class Ticket {
    // 票数
    private int number = 30;

    // 操作方法:卖票
    synchronized void sale() {
        // 判断是否卖票
        if (number > 0) {
            System.out.println(Thread.currentThread().getName() + "=>sale:" + (number--) + ",剩余:" + number);
        }
    }
}

public class SaleTicket {
    /**
     * 第二步,创建多个线程,调用资源类的操作方式
     */
    public static void main(String[] args) {
        // 创建Ticket对象
        Ticket ticket = new Ticket();
        // 创建三个线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 调用卖票方法
                for (int i = 0; i < 15; i++) {
                    ticket.sale();
                }
            }
        }, "t1").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                // 调用卖票方法
                for (int i = 0; i < 15; i++) {
                    ticket.sale();
                }
            }
        }, "t2").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                // 调用卖票方法
                for (int i = 0; i < 15; i++) {
                    ticket.sale();
                }
            }
        }, "t3").start();
    }
}

/********************* 控制台信息 情况1 *************************/
t1=>sale:30,剩余:29
t1=>sale:29,剩余:28
t1=>sale:28,剩余:27
t1=>sale:27,剩余:26
t1=>sale:26,剩余:25
t1=>sale:25,剩余:24
t1=>sale:24,剩余:23
t1=>sale:23,剩余:22
t1=>sale:22,剩余:21
t1=>sale:21,剩余:20
t1=>sale:20,剩余:19
t1=>sale:19,剩余:18
t1=>sale:18,剩余:17
t1=>sale:17,剩余:16
t1=>sale:16,剩余:15
// t1线程对ticket对象进行了释放,之后t2马上调用方法使得ticket对象重新获得锁
t2=>sale:15,剩余:14
t2=>sale:14,剩余:13
t2=>sale:13,剩余:12
t2=>sale:12,剩余:11
t2=>sale:11,剩余:10
t2=>sale:10,剩余:9
t2=>sale:9,剩余:8
t2=>sale:8,剩余:7
t2=>sale:7,剩余:6
t2=>sale:6,剩余:5
t2=>sale:5,剩余:4
t2=>sale:4,剩余:3
t2=>sale:3,剩余:2
t2=>sale:2,剩余:1
t2=>sale:1,剩余:0

/********************* 控制台信息 情况2*************************/
t1=>sale:30,剩余:29
t1=>sale:29,剩余:28
t1=>sale:28,剩余:27
t1=>sale:27,剩余:26
t1=>sale:26,剩余:25
t1=>sale:25,剩余:24
t1=>sale:24,剩余:23
t1=>sale:23,剩余:22
t1=>sale:22,剩余:21
t1=>sale:21,剩余:20
t1=>sale:20,剩余:19
// t1线程对ticket对象进行了释放,之后t2马上调用方法使得ticket对象重新获得锁
t2=>sale:19,剩余:18
t2=>sale:18,剩余:17
t2=>sale:17,剩余:16
t2=>sale:16,剩余:15
t2=>sale:15,剩余:14
t2=>sale:14,剩余:13
t2=>sale:13,剩余:12
t2=>sale:12,剩余:11
t2=>sale:11,剩余:10
t2=>sale:10,剩余:9
t2=>sale:9,剩余:8
t2=>sale:8,剩余:7
t2=>sale:7,剩余:6
t2=>sale:6,剩余:5
t2=>sale:5,剩余:4
// t2线程对ticket对象进行了释放,之后t1马上调用方法使得ticket对象重新获得锁
t1=>sale:4,剩余:3
t1=>sale:3,剩余:2
t1=>sale:2,剩余:1
t1=>sale:1,剩余:0

那么如果这个获取锁的线程由于要等待 IO 或者其他原因(比如调用 sleep 方法)被阻塞了,但是又没有释放锁,其他线程便只能干巴巴地等待,试想一 下,这多么影响程序执行效率。

因此就需要有一种机制可以不让等待的线程一直无期限地等待下去(比如只等 待一定的时间或者能够响应中断),通过 Lock 就可以办到。

(更新中)

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-07 13:43:18  更:2021-10-07 13:44:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 18:24:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码