自学内容网 自学内容网

【java】锁机制

1. 背景

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对象 都可以充当对象 但是要保证是同一个

// 语法
sychronized(锁对象){
    // 代码 对共享数据的操作 
    // 把非原子操作变成原子操作
}
// 谁能够充当锁对象
任意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

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对象)

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 方法和语句可获得的更广泛的锁定操作

- lock()  加锁
- unlock() 释放锁
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();
            }
        }
    }
}

原文地址:https://blog.csdn.net/qq_26127905/article/details/144357132

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!