多线程代码块同步——抢火车票

用之前学习的线程方法去写(有bug): 

package com.ytzl.第3章.dmeo1多线程.two;
/*多线程之同步代码块*/
/*模拟网络抢票*/
public class one implements Runnable{

    private int count=10;//记录抢票次数
    private int num=0;//记录买到第几张票

    public static void main(String[] args) {
        one site = new one();
        Thread p1 = new Thread(site,"携程");
        Thread p2 = new Thread(site,"黄牛");
        Thread p3 = new Thread(site,"支付");
        System.out.println("*******开始抢票*******");
        p1.start();
        p2.start();
        p3.start();
    }

    @Override
    public void run() {
        while (true){
            //同步方法,一次只有一个线程能使用当前方法
            //sale();
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //同步代码块,一次只有一个线程能使用代码块
                if (count<=0) {
                    break;
                }
                num++;
                count--;
                System.out.println(Thread.currentThread().getName()+"抢到第"+num+"张票,剩余"+count+"张票!");
            }
        }
    }

当我们去以之前的写法同时运行多个线程程序时,它们会同时去抢一个进程,会出现如下结果:

会出现多个线程抢到同一张票,这样就会减低一定的运行速度,我们需要在里边加入一个方法

synchronized(){};

去抢,它的作用是同步代码块,将我们需要执行的代码放入该方法即可,同一时刻只能有一个线程进入synchronized{}同步状态,当一个线程被同步的时候,其他线程代码同样是被锁定的,代码块锁定时,其他线程可以访问非同步代码,通俗的来讲就是当其中一个线程在执行这个状态时,其它线程则不能去执行,只能去执行下一个状态代码。

完善后的代码如下:

package com.ytzl.第3章.dmeo1多线程.two;
/*多线程之同步代码块*/
/*模拟网络抢票*/
public class one implements Runnable {

    private int count = 10;//记录抢票次数
    private int num = 0;//记录买到第几张票

    public static void main(String[] args) {
        one site = new one();
        Thread p1 = new Thread(site, "携程");
        Thread p2 = new Thread(site, "黄牛");
        Thread p3 = new Thread(site, "支付");
        System.out.println("*******开始抢票*******");
        p1.start();
        p2.start();
        p3.start();
    }

    @Override
    public void run() {
        while (true) {
            //同步方法,一次只有一个线程能使用当前方法
            //sale();
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //同步代码块,一次只有一个线程能使用代码块
            synchronized (this) {
                /*
                 * 多线程在高并发访问同一资源的时候
                 * 同一时刻只能有一个线程进入synchronized同步状态
                 * 当一个线程被同步的时候,其他线程代码块同样是被锁定的
                 * 代码快锁定的,其他线程可以访问非同步代码
                 * */
                if (count <= 0) {
                    break;
                }
                num++;
                count--;
                System.out.println(Thread.currentThread().getName() + "抢到第" + num + "张票,剩余" + count + "张票!");
            }
        }
    }
}

运行结果如下:

猜你喜欢

转载自blog.csdn.net/ypf3442354429/article/details/124872481