synchronized实现简单售票实例(sychronized代码块、synchronized方法)

一、synchronized代码块实现售票

1、首先synchronized就像一把锁,多个线程同时竞争synchronized代码块的资源,当一个线程先抢到这个资源时,就会上锁,别的线程就不能访问,只能等到当前线程执行完sychronized里面的代码才会释放锁,然后别的线程才可以竞争访问,接着又是上锁和释放锁的过程。
2、synchronized实现简单售票代码:

import java.util.concurrent.TimeUnit;

/**
 * synchronized代码块实现简单售票
 * 
 * @author limingxing
 *
 */
public class SaleTest {
    public static void main(String[] args) {
        SaleTicket st = new SaleTicket();
        //三个线程同时售票
        new Thread(st).start();
        new Thread(st).start();
        new Thread(st).start();
    }
}

class SaleTicket implements Runnable {
    private int ticket = 20;//假设有20张票
    @Override
    public void run() {
            while (true) {
            synchronized (this) {
                try {
                    //使当前线程休眠1秒,休眠期间不会释放锁,其它线程不能访问。
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (ticket == 1) {
                    --ticket;
                    System.out.println(Thread.currentThread().getName() + ":售一张,票售完了");
                    break;
                } else if(ticket == 0){
                    System.out.println(Thread.currentThread().getName() + ":票售完了");
                    break;
                }else {
                    System.out.println(Thread.currentThread().getName() + ":售一张,票还剩:" + (--ticket) + "张");
                }
            }
        }
    }
}

3、结果
结果
4、上面有三个线程去售票,假设为A、B、C三个线程,假设此时都到Run方法中while(true)里面了,这时候A先得到锁,然后B、C都被阻挡在锁的外面,一直等待锁的释放,当A执行完所里面的代码,就会释放锁;三个线程又同时竞争锁,再释放锁,就一直循环下去,一直到票售完了,跳出循环,结束售票。

二、synchronized修饰方法实现简单售票

1、原理和代码块差不多,用synchronized关键字修饰方法,将方法的内容锁起来,方法里面的内容每次只能让一个线程访问。
2、代码

import java.util.concurrent.TimeUnit;

/**
 * synchronized方法
 * @author limingxing
 *
 */
public class SaleTest2 {
    public static void main(String[] args) {
        TicketTest tt = new TicketTest();
        new Thread(tt).start();
        new Thread(tt).start();
        new Thread(tt).start();
    }
}
class TicketTest implements Runnable{
    private int ticket = 20;
    @Override
    public void run() {
        while(true) {
            if(!sale()) {
                break;
            }
        }
    }
    public synchronized boolean sale() {
        try {
            //使当前线程休眠1秒,休眠期间不会释放锁,其它线程不能访问。
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (ticket == 1) {
            --ticket;
            System.out.println(Thread.currentThread().getName() + ":售一张,票售完了");
            return false;
        } else if(ticket == 0){
            System.out.println(Thread.currentThread().getName() + ":票售完了");
            return false;
        }else {
            System.out.println(Thread.currentThread().getName() + ":售一张,票还剩:" + (--ticket) + "张");
            return true;
        }

    }
}

3、结果
结果

猜你喜欢

转载自blog.csdn.net/qq_37155198/article/details/81587027
今日推荐