【java】锁机制

文章目录

  • [1. 背景](#1. 背景)
  • [2. synchronized同步](#2. synchronized同步)
    • [2.1 synchronized同步代码块](#2.1 synchronized同步代码块)
    • [2.2 synchronized同步方法](#2.2 synchronized同步方法)
    • [2.3 synchronized静态方法](#2.3 synchronized静态方法)
  • [3. Lock](#3. Lock)

1. 背景

java 复制代码
public class Demo2 {
    public static void main(String[] args) {
        // 创建子类对象
        SellWindow2 sellWindow2 = new SellWindow2();
        // 创建3个线程模拟窗口
        Thread t1 = new Thread(sellWindow2);
        Thread t2 = new Thread(sellWindow2);
        Thread t3 = new Thread(sellWindow2);
        t1.setName("A窗口");
        t2.setName("B窗口");
        t3.setName("C窗口");
        t1.start();
        t2.start();
        t3.start();
        //- 会有重复的票 - 会有不存在的票0  -1
    }
}

class SellWindow2 implements Runnable{
    int tickets = 100;
    @Override
    public void run() {
        while (true) {
            // 重复的原因
            // 假设A抢到CPU执行权 此时tickets=100
            // 如果B抢到了CPU的执行权 此时票为100 B也进来
            // C也抢到  此时票是100

            // 不存在的原因
            // 假设A抢到CPU的执行权 此时tickets = 1
            // B也抢到 此时 tickets = 1  也进来
            // c执行  此时 tickets = 1  也进来
            if (tickets > 0) {
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+
                        "卖了第" + tickets-- + "票");
                // tickets--可以分为几步 1.取值 2.-1操作 3.赋予新值
                // A 卖了第100
                // B 卖了第100

                // 最坏情况
                // A窗口卖了第1张票 此时还剩0张
                // B窗口卖了第0张票 此时还剩-1
                // C窗口卖了第-1张票 此时还剩-2
            }
        }
    }
}

2. synchronized同步

2.1 synchronized同步代码块

任意java对象 都可以充当对象 但是要保证是同一个

java 复制代码
// 语法
sychronized(锁对象){
    // 代码 对共享数据的操作 
    // 把非原子操作变成原子操作
}
// 谁能够充当锁对象
任意java对象 都可以充当对象 但是要保证是同一个
java 复制代码
public class Demo1 {
    public static void main(String[] args) {
        SellWindow sellWindow = new SellWindow();
        // 创建3个线程
        Thread thread = new Thread(sellWindow);
        Thread thread2 = new Thread(sellWindow);
        Thread thread3 = new Thread(sellWindow);
        thread.setName("A");
        thread2.setName("B");
        thread3.setName("c");
        // STRART
        thread.start();
        thread2.start();
        thread3.start();
    }
}

class SellWindow implements Runnable{
    int tickets = 100;
    A obj = new A();
    @Override
    public void run() {
        while (true) {
            synchronized (obj) {
                if (tickets > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+
                            "卖了第" + tickets-- +" 票");
                }
            }

        }
    }
}
class A{

}

2.2 synchronized同步方法

同步方法中的锁对象是this

java 复制代码
public class Demo2 {
    public static void main(String[] args) {
        SellWindow2 sellWindow = new SellWindow2();
        // 创建3个线程
        Thread thread = new Thread(sellWindow);
        Thread thread2 = new Thread(sellWindow);
        Thread thread3 = new Thread(sellWindow);
        thread.setName("A");
        thread2.setName("B");
        thread3.setName("c");
        // STRART
        thread.start();
        thread2.start();
        thread3.start();
    }
}

class SellWindow2 implements Runnable {
    int tickets = 100;
    //A obj = new A();
    int i = 0;

    @Override
    public void run() {
        while (true) {

            if (i % 2 == 0) {
                synchronized (this) {
                    if (tickets > 0) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() +
                                "卖了第" + tickets-- + " 票");
                    }
                }
            } else {
                sell();
            }
            i++;


        }

    }

    private synchronized void sell() {

        if (tickets > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() +
                    "卖了第" + tickets-- + " 票");
        }

    }

}
class A {

}

2.3 synchronized静态方法

静态方法中的锁对象是字节码文件对象 (.class对象)

java 复制代码
public class Demo2 {
    public static void main(String[] args) {
        SellWindow2 sellWindow = new SellWindow2();
        // 创建3个线程
        Thread thread = new Thread(sellWindow);
        Thread thread2 = new Thread(sellWindow);
        Thread thread3 = new Thread(sellWindow);
        thread.setName("A");
        thread2.setName("B");
        thread3.setName("c");
        // STRART
        thread.start();
        thread2.start();
        thread3.start();
    }
}

class SellWindow2 implements Runnable {
    static int tickets = 100;
    Object obj = new Object();
    int i = 0;

    @Override
    public void run() {
        while (true) {

            if (i % 2 == 0) {
                // 对象.getClass
                // 类名.class
                synchronized (SellWindow2.class) {
                    if (tickets > 0) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() +
                                "卖了第" + tickets-- + " 票");
                    }
                }
            } else {
                sell();
            }
            i++;


        }

    }

    private static synchronized void sell() {

        if (tickets > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() +
                    "卖了第" + tickets-- + " 票");
        }

    }

}

class B {

}

3. Lock

Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作

java 复制代码
- lock()  加锁
- unlock() 释放锁
java 复制代码
public class Demo3 {
    public static void main(String[] args) {
        SellWindow3 sellWindow = new SellWindow3();
        // 创建3个线程
        Thread thread = new Thread(sellWindow);
        Thread thread2 = new Thread(sellWindow);
        Thread thread3 = new Thread(sellWindow);
        thread.setName("A");
        thread2.setName("B");
        thread3.setName("c");
        // STRART
        thread.start();
        thread2.start();
        thread3.start();
    }
}

class SellWindow3 implements Runnable{
    int tickets = 100;
    Lock lock = new ReentrantLock();
    @Override
    public void run() {
        while (true) {
            // 加锁
            lock.lock();
            try{
                // 对共享资源的操作
                if (tickets > 0) {
                    Thread.sleep(200);
                    System.out.println(Thread.currentThread().getName()
                    +"卖了第" + tickets-- + "票");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                // 释放锁
                lock.unlock();
            }
        }
    }
}
相关推荐
邓熙榆14 分钟前
Logo语言的网络编程
开发语言·后端·golang
graceyun17 分钟前
C语言进阶习题【1】指针和数组(4)——指针笔试题3
android·java·c语言
我科绝伦(Huanhuan Zhou)21 分钟前
Linux 系统服务开机自启动指导手册
java·linux·服务器
旦沐已成舟1 小时前
K8S-Pod的环境变量,重启策略,数据持久化,资源限制
java·docker·kubernetes
S-X-S1 小时前
项目集成ELK
java·开发语言·elk
Ting-yu1 小时前
项目实战--网页五子棋(游戏大厅)(3)
java·java-ee·maven·intellij-idea
Johaden2 小时前
EXCEL+Python搞定数据处理(第一部分:Python入门-第2章:开发环境)
开发语言·vscode·python·conda·excel
ByteBlossom6666 小时前
MDX语言的语法糖
开发语言·后端·golang
程序研6 小时前
JAVA之外观模式
java·设计模式
计算机学姐6 小时前
基于微信小程序的驾校预约小程序
java·vue.js·spring boot·后端·spring·微信小程序·小程序