解决线程安全问题_同步方法和解决线程安全问题_Lock锁

解决线程安全问题_同步方法

package com.yang.Test.ThreadStudy;

import lombok.SneakyThrows;

/**
 * 卖票案例出现了线程安全的问题
 * 卖出了不存在的票和重复的票
 * 解决线程安全问题的二种方案:使用同步方法
 * 使用步骤:
 * 1.把访问了共享数据的代码抽取出来,放到一个方法中
 * 2.在方法上添加synchronized修饰符
 *
 * 格式:定义方法的格式
 * 修饰符 synchronized 返回值类型 方法名(参数列表){
 *     可能会出现线程安全问题的代码(访问了共享数据的代码)
 * }
 */
public class RunnableImpl implements Runnable{
    private int ticket = 100;

    @SneakyThrows
    @Override
    public void run() {
        while(true){
            payTicket();
        }
    }


    /**
     * 定义一个同步方法
     * 同步方法也会把内部代码锁住
     * 只让一个线程执行
     * 同步方法的锁对象就是实现类对象
     * 也就是this
     */
    public synchronized void payTicket(){
        if (ticket>0){
            System.out.println(Thread.currentThread().getName()+"--->正在卖第"+ticket+"张票");
            ticket--;
        }
    }
}
package com.yang.Test.ThreadStudy;

public class DemoTicket {
    public static void main(String[] args) {
        RunnableImpl r1 = new RunnableImpl();
        new Thread(r1).start();
        new Thread(r1).start();
        new Thread(r1).start();
    }
}

线程安全问题_Lock锁

java java.util.concurrent.locks.Lock机制提供了比synchronized代码快和synchronized方法更广泛的锁定操作,同步代码块/同步方法具有的功能Lock都有,初次之外更强大,更体现面向对象。
Lock锁也成为同步锁,枷锁与释放方法如下:
public void lock();加同步锁
public void unlock();释放同步锁

package com.yang.Test.ThreadStudy;

import lombok.SneakyThrows;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class RunnableImpl implements Runnable{
    private int ticket = 100;
    Lock lock = new ReentrantLock();
    @SneakyThrows
    @Override
    public void run() {
        while(true){
            lock.lock();
            if (ticket>0){
                System.out.println(Thread.currentThread().getName()+"--->正在卖第"+ticket+"张票");
                ticket--;
            }
            lock.unlock();
        }
    }

}

package com.yang.Test.ThreadStudy;

public class DemoTicket {
    public static void main(String[] args) {
        RunnableImpl r1 = new RunnableImpl();
        new Thread(r1).start();
        new Thread(r1).start();
        new Thread(r1).start();
    }
}

posted @ 2022-07-08 10:49  我滴妈老弟  阅读(18)  评论(0编辑  收藏  举报