探究线程同步

在方法返回值类型前加上 synchronized ,意味着一旦有线程执行了该方法,该线程就上锁了,只有到该方法执行完,也就是return 后,锁才被释放,这个过程中从始至终只有一个线程操作。也就是线程同步。

例如:

public synchronized static void main(String[] args){}
private synchronized void run(){}
//以下也行
synchronized private void run(){}

或者 同步代码块

private void run(){
    synchronized(this){
        
    }
}

首先来看为什么会有线程同步:

java中默认是异步线程

【举例】

一张电子饭卡小明和小红共用(电子卡才有可能两人在同一时间使用)

public class Card {
    private static int money = 80;

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }

    //取款
    public void chargeMoney(int money){
        this.money -= money ;
    }
}

public class People implements Runnable{
    //在People初始化时就已经初始化Card
    private Card card = new Card();
    @Override
    public void run() {

        for(int i = 0 ; i < 5 ;i++){
           chargeMoney(10);
           if(card.getMoney()<0){
               System.out.println("卡里没钱了!");
           }
       }

    }
    public void chargeMoney(int mon) {
        if(card.getMoney() >= mon){
            try {
                Thread.sleep(2000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            card.chargeMoney(mon);
            System.out.println(Thread.currentThread().getName()+" 先生/女士,已成功扣款 "+mon+" 元,余额为 "+ card.getMoney());
        }else{
            System.out.println(Thread.currentThread().getName()+" 先生/女士,不好意思,你的饭卡已透支,余额仅有 "+card.getMoney());
        }
    }
}

public class Main {
    public static void main(String[] args) {
        People people = new People();
        Thread thread1 = new Thread(people,"小明");
        Thread thread2 = new Thread(people,"小红");
        thread1.start();
        thread2.start();
    }
}

运行结果:

 

由于默认是异步线程,所以当两人同时消费时,就会出现上述混乱情况(当一个人付完款显示余额时,其实那个余额并不是实际上的)。

而实际生活中,为了避免这种情况的发生,最好的方法就是限定同一时间只能有一个人付款,也就是只允许某个线程对资源进行操作,也就是锁的概念了。

改进方法:在线程执行方法前加上 synchronized ,使执行该方法只能是一个线程。

 public synchronized void run() {
     
        for(int i = 0 ; i < 5 ;i++){
           chargeMoney(10);
           if(card.getMoney()<0){
               System.out.println("卡里没钱了!");
           }
       }

    }

运行结果:

 

这里是因为连续五次

进行扣款,所以一直都是一个线程在操作,实际过程就是小明付完一次后,小红就能付了。

这就是同步的意义。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值