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());
    }
}
原文地址:https://www.cnblogs.com/li33/p/12719179.html