ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

syncronized如何上锁

2020-04-17 13:04:25  阅读:235  来源: 互联网

标签:account Thread int 上锁 如何 new public syncronized


上锁,根据操作系统所说的原则,对共享变量上锁,对临界区上锁。谁访问临界资源?就给谁上锁

同步监视器,它上锁的对象。
1.用关键字给方法上锁
2.用synchronized代码块上锁

默认上锁对象:this,指向自身。就是调用这个方法的对象,给他上锁。

安全的买票(给方法上锁)

public class SynchronizeTest {
    //线程不安全
    public static void main(String[] args) {
        BuyTicker buyTicker = new BuyTicker();
        new Thread(buyTicker,"lhh").start();
        new Thread(buyTicker,"jhj").start();
        new Thread(buyTicker,"黄牛").start();
    }
}
class BuyTicker implements Runnable{
    private int ticketNum = 10;
    boolean flag = true;
    @Override
    public void run() {
        while(flag){//外部停止方式
            try {
                buy();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }//对买票上锁,锁的this,this是指当前的对象。
    public synchronized void buy() throws InterruptedException {//直接给方法上锁
        //判断是否有票
        if(ticketNum<=0){
            System.out.println(Thread.currentThread().getName()+"票卖完了");
            flag = false;
            return;
        }
        Thread.sleep(100);
        System.out.println(Thread.currentThread().getName()+"拿到"+ticketNum--);
    }
}

安全的银行(给临界区上锁,)

如果给一个类的方法上锁了,实际上是给this也就是调用方法的这个对象上锁,比如你要是给run()上锁,就相当于你去取钱把银行锁了。但是取钱的人都还在银行里面。所以是要对账户上锁,因为我们逍遥操控的变量就是账户。

public class UnsafeBake {
    public static void main(String[] args) {
        Account account = new Account("结婚基金",1000);
        Draw you = new Draw(account,50,"你");
        Draw girlFriend = new Draw(account,100,"女朋友");
        you.start();
        girlFriend.start();
    }
}
class Account{
    String name;
    int money;
    public Account(String name, int money) {
        this.name = name;
        this.money = money;
    }
}
class Draw extends Thread{
    Account account;
    int drawMoney;
    int noMoney;
    public Draw(Account account, int drawMoney, String name) {
        super(name);
        this.account = account;
        this.drawMoney = drawMoney;
    }
    @Override
    public void run() {
        synchronized (account){
            if(account.money-drawMoney<0){
                System.out.println("余额不足");
                return;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            account.money = account.money - drawMoney;
            noMoney = noMoney +drawMoney;
            System.out.println(account.name+"余额为:"+account.money);
            System.out.println(this.getName()+"手里的钱"+noMoney);//继承THread可以直接写this
        }
    }
}

安全的列表

public class UnsafeList {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        for (int i = 0; i < 100; i++) {
            new Thread(()->{//lambda表达式
                synchronized (list){//上锁临界资源list,下面是临界区操作临界资源的代码
                    list.add(Thread.currentThread().getName());
                }
            }).start();
        }
        try {
            Thread.sleep(1000);//如果不让他睡,程序结束的时候线程也结束了一半了,列表元素就不够100
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(list.size());
    }
}

标签:account,Thread,int,上锁,如何,new,public,syncronized
来源: https://www.cnblogs.com/li33/p/12719179.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有