解决线程安全问题_同步方法和解决线程安全问题_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();
}
}