Java中synchronized基本介绍和细节讨论。使用Synchronized来解决售票超卖问题

基本介绍

线程同步机制:在多线程编程下,一些敏感数据不允许被多个现在在同一时刻访问,此时就使用同步访问机制,保证数据在任何同一时刻最多只有一个进程访问,以保证数据的完整性。(即:当有一个线程在对内存操作时,其他的线程都不允许对这个内存地址进行操作,指代该线程完成操作,其他的线程才能对内存地址进行操作

细节讨论

  1. 关键字synchronized来与对象的互斥锁联系。当某个对象来用synchronized修饰时,表明该对象在任何一时刻只能由一个线程访问
  2. 同步的局限性:导致程序的执行效率低,因为同一时刻只能执行一个线程
  3. sychronized可以修饰方法也可以修饰代码块,分别称为同步方法和同步代码块。一般情况下建议使用同步代码块,因为这样的效率要高一些
  4. 同步方法(非静态)的锁对象可以是this,也可以是其他对象(要求是同一个对象)
  5. 同步方法(静态的)的锁对象是当前类本身

使用synchronized来处理售票时线程同步的问题:
代码:

public class Threads {
    public static void main(String[] args) {
        //会出现票超卖现象,原因:当我们还有1张票时,可能一下子来了2个线程,此时判断是否<=0时都不小于,所以继续往下执行卖票,导致票超卖现象
        Windows windows = new Windows();
        //同一个对象
        Thread thread1 = new Thread(windows);
        thread1.setName("窗口1");//设置线程的名字			
        Thread thread2 = new Thread(windows);
        thread2.setName("窗口1");
        Thread thread3 = new Thread(windows);
        thread3.setName("窗口3");

        thread1.start();
        thread2.start();
        thread3.start();
    }
}

class Windows implements Runnable {

    private static int tickets = 100;//共享100张票
    private /*static*/ Boolean loop = true;//控制run方法变量

    public /*static*/ void sell() {//同步方法
//        Object object = new Object();
        synchronized (/*当方法为静态时锁对象是当前类本身为:Windows.class*/this/*当为非静态方法时也可以为object,因为object是这个类的对象,是同一个对象*/) {
            if (tickets <= 0) {
                System.out.println("没票了");
                loop = false;
                return;
            }

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName() + "卖了一张票,还剩" + (--tickets));
        }
    }

    @Override
    public void run() {
        while (loop) {
            sell();
//            synchronized (this) {//同步代码块
//                if (tickets <= 0) {
//                    System.out.println("没票了");
//                    loop = false;
//                    return;
//                }
//
//                try {
//                    Thread.sleep(10);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//
//                System.out.println("窗口" + Thread.currentThread().getName() + "卖了一张票,还剩" + (--tickets));
//            }
        }
    }
}

注意:一定要是同一个对象,如上述的windows。如果是不同的对象的话,相当于是不同的对象锁了,也就是不只一把锁,各用各的,当然就起不到线程同步了。比如:你要进厕所去方便,现在这个房间的门就相当于是对象锁,只能等里面的人出来后你在进入。若此时是不同的对象的话,就相当于有不同的门,也就是说现在这个厕所有不同的门可以进入了,那样就起不到防护机制了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值