Synchronized 线程同步

当用多线程处理一个卖票问题时 设置3个线程窗口 一起进行卖票

public class ThreadTestSync {
    public static void main(String[] args) {
        SellTicket sellTicket = new SellTicket();

        Thread sell01 = new Thread(sellTicket);// 窗口1
        sell01.setName("窗口1");
        Thread sell02 = new Thread(sellTicket);// 窗口2
        sell02.setName("窗口2");
        Thread sell03 = new Thread(sellTicket);// 窗口3
        sell03.setName("窗口3");
        sell01.start();
        sell02.start();
        sell03.start();
    }

}

class SellTicket implements Runnable {
    private int ticketNum = 100; //票总数
    private boolean loop = true;
    private int count;

    public void sell() {
        while (loop) {
                if (ticketNum <= 0) {
                    System.out.println("票已经售罄");
                    break;
                }
                System.out.println(Thread.currentThread().getName() + "售出第" + (++count) 
                + "张票 还剩下" + (--ticketNum) + "张票");
            try {
                Thread.sleep(100);//休眠100毫秒
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    public void run() {
        sell();
    }
}

结果中出现了票已售罄 还在出售的情况 证明当判断到达临界条件时 同时有多个线程进入 要求在判断与售卖过程中只允许一个线程进入 进行线程同步 即当有一个线程对内存进行操作时 其他线程都不可以对这个内存地址进行操作 直到该线程完成操作

同步方法-Synchronized

synchronized(对象) { //得到对象锁才可进入同步代码
//同步代码
}
synchronized也可声明方法 表示该方法为同步方法
每一个对象都对应一个互斥锁 这个用于保证 在任何同一时刻只能有一个线程访问该对象 关键字synchronized用来与对象的互斥锁联系
因为同步代码 要求在同一时刻只能有一个线程访问 导致程序的执行效率降低
所以需要被同步的代码 应尽可能的少 因此需线程同步时 应使用同步代码块的方式

class SellTicket implements Runnable {
    private int ticketNum = 100; //票总数
    private boolean loop = true;
    private int count;

    public void sell() {
        while (loop) {
            synchronized (this) { //需要被同步的代码
                if (ticketNum <= 0) {
                    System.out.println("票已经售罄");
                    break;
                }
                System.out.println(Thread.currentThread().getName() + "售出第" + (++count)
                        + "张票 还剩下" + (--ticketNum) + "张票");
            }
            try {
                Thread.sleep(100);//休眠100毫秒
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    public void run() {
        sell();
    }
}

继承Thread创建线程 实现同步

class SellTicket02 extends Thread{
    private static int ticketNum = 100; //票总数
    private static boolean loop = true;
    private static int count;

    public void sell() {
        while (loop) {
            synchronized (this) { //需要被同步的代码
                if (ticketNum <= 0) {
                    System.out.println("票已经售罄");
                    break;
                }
                System.out.println(Thread.currentThread().getName() + "售出第" + (++count)
                        + "张票 还剩下" + (--ticketNum) + "张票");
            }
            try {
                Thread.sleep(100);//休眠100毫秒
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
    @Override
    public void run() {
        sell();
    }
}

在非静态同步方法中的锁可以是this 也可是其他的 同一个对象
而静态的同步方法的 锁为当前类本身

当继承 Thread类 创建线程 使用上面实现Runnable接口 线程同步的方式后发现并没有限制住线程进入 其原因是继承Thread类创建线程 在调用时 new 三个不同的对象 去执行线程 每个对象都对应了一把互斥锁 进入同步代码时每个对象都可以拿到自己锁进入同步代码 需要这三个对象共用一把互斥锁才可实现线程同步 可进行以下修改

public static void sell() {//将该方法设置为静态方法
...
synchronized (SellTicket02.class) {//静态的同步方法的 锁为当前类本身
....
}
....
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值