这篇文章我将采用故事案例来进行对线程的上锁和解锁的讲解,让编程小白也能理解线程的概念以及对线程的认识和学会使用的方法
创建线程的几种方法:
1、创建一个类继承Thread类,重写run()方法,将所要完成的任务代码写进run()方法中;
2、创建一个类并实现Runnable接口,重写run()方法,创建实现Runnable接口的类的对象,将该对象当做Thread类的构造方法中的参数传进去;
3、实现Callable接口,创建一个类并实现Callable接口,重写call()方法,将所要完成的任务的代码写进call()方法中,需要注意的是call()方法有返回值,并且可以抛出异常;
这里我们所讲的是第二种实现Runnable接口也是最常用的一种:
import java.util.concurrent.locks.ReentrantLock;
public class threadTest{
static int count=100;
public static void main(String[] args) {
//创建lock锁对象
ReentrantLock lock=new ReentrantLock();
//Runnable创建线程采用了lambda表达式
Runnable runBle=() -> {
while (count >0 ) {
//上锁
lock.lock();
if(count<=0) {
return;
}
System.out.println(Thread.currentThread().getName()+"卖出,当前票数剩余:"+--count);
//解锁
lock.unlock();
}
};
//模拟售票员
Thread t1=new Thread(runBle,"张三");
Thread t2=new Thread(runBle, "李四");
Thread t3=new Thread(runBle, "王五");
t1.start();
t2.start();
t3.start();
}
}
我们这里采用的是火车站售票的模式,进行对线程的讲解,我们在全国各地都能购买同一趟列车的火车票这就是很多线程共享同一个数据,我们把每一个线程当作一个售票员,全国的售票员当在对同一列车的票进行操作时,火车票的票数就会出现同时操作余票和计算余票票数时的问题,当我们操作时肯定是同时对余票进行了减少其中就会出现,A售票员操作比较快已经把票销售出去了,但是同时B售票员则正在对票进行出售,但是这其中就会出现对余票的计算问题,相当于同时进入了一个方法里面当A售票员执行完成,B售票员同时也对余票进行操作完毕,但是B售票员操作的余票票数是B售票员最开始看到的票数所以A售票员和B售票员进行交互时就会出现余票计算的问题如下:
import java.util.concurrent.locks.ReentrantLock;
public class threadTest{
static int count=100;
public static void main(String[] args) {
//创建lock锁对象
ReentrantLock lock=new ReentrantLock();
//Runnable创建线程采用了lambda表达式
Runnable runBle=() -> {
while (count >0 ) {
System.out.println(Thread.currentThread().getName()+"卖出,当前票数剩余:"+--count);
}
};
//模拟售票员
Thread t1=new Thread(runBle,"张三");
Thread t2=new Thread(runBle, "李四");
Thread t3=new Thread(runBle, "王五");
t1.start();
t2.start();
t3.start();
}
}
所以我们才需要对线程进行加锁,加锁的意思是当A售票员在进行售票时B售票员会被阻挡在循环外,这样B售票员在对余票进行操作时,得到的余票是A售票员操作后剩余的票数,这样就不会出现票数计算的问题最终结果如下:
import java.util.concurrent.locks.ReentrantLock;
public class threadTest{
static int count=100;
public static void main(String[] args) {
//创建lock锁对象
ReentrantLock lock=new ReentrantLock();
//Runnable创建线程采用了lambda表达式
Runnable runBle=() -> {
while (count >0 ) {
//上锁
lock.lock();
if(count<=0) {
return;
}
System.out.println(Thread.currentThread().getName()+"卖出,当前票数剩余:"+--count);
//解锁
lock.unlock();
}
};
//模拟售票员
Thread t1=new Thread(runBle,"张三");
Thread t2=new Thread(runBle, "李四");
Thread t3=new Thread(runBle, "王五");
t1.start();
t2.start();
t3.start();
}
}
加上锁之后他们交互后的票数是不是就正常了呢,至于我们为什么要 if 判断一下呢,你们可以把if去掉试试看就知道了。
当你们试过之后可能就会发现定义了三个对象(三个售票员)但不是每一个售票员都能抢到票的,每次运行得到的售票员结果都是不一样的,这个就涉及到了线程抢占CPU时间片的问题了,之后会持续更新。
看到这的小伙伴们相信都是非常热爱学习的,关注评论点个赞再走吧!!!,欢迎大佬指出不对的地方!!!
————————————————
版权声明:本文为CSDN博主「江柯一梦」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_666123/article/details/104815495
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。