在多线程中典型的问题就是卖票问题,如果同步处理的不好则有可能出现一票多卖的情况,或者出现票超售的现象。因此就必须加锁。
首先需要知道线程的实现有哪几种方式,通常有继承Thread类与实现Runable接口Callable接口,以及线程池实现
下面用代码的形式进行说明
这是在lock锁实现Runable接口实现的方法继承Thread类似
public class ThreadDemo implements Runnable {
private Integer tip = 100;
private final Lock lock=new ReentrantLock();
@Override
public void run() {
while (true){
if (tip>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
save();
}else {
break;
}
}
}
private void save(){
lock.lock();
try {
if (tip>0){
System.out.println(Thread.currentThread().getName()+"卖出了"+tip);
tip--;
}
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
在这说明一下,有人纳闷为什么在下面还要判断一下tip是否>0因为可能在--没做完的时候几个线程都进来了,这样就出现了超售现象。
下面写测试类
package threaddemo;
/**
* @Author: taoqianlilang
* @Description:
* @Date: Created in 16:24 2020/4/28
* @Modified By:
*/
public class test {
public static void main(String[] args) {
ThreadDemo my=new ThreadDemo();
Thread thread1=new Thread(my,"1号窗口");
Thread thread2=new Thread(my,"2号窗口");
Thread thread3=new Thread(my,"3号窗口");
thread1.start();
thread2.start();
thread3.start();
}
}
展示下测试的结果
下面介绍下使用synchronized实现的,测试类改个new的类就好。
package threaddemo;
import jdk.nashorn.internal.ir.WhileNode;
/**
* @Author: taoqianlilang
* @Description:
* @Date: Created in 19:43 2020/4/28
* @Modified By:
*/
public class ThreadDemo02 implements Runnable{
private Integer tip=100;
@Override
public void run() {
while (true){
synchronized (this){
if (tip>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"卖出了"+tip);
tip--;
}else {
break;
}
}
}
}
}
有的博客会把锁写在run方法那上面,如果这样写的话就会出现一个线程直接从头到尾买票的情况,那多窗口卖票就没意义了。
这样的测试结果如下图