同步锁

关于synchronized的初步理解

package syn;

public class UnsafeBuyTicket {
    public static void main(String[] args) {
        BuyTicket buyTicket = new BuyTicket();
        new Thread(buyTicket,"我").start();
        new Thread(buyTicket,"你").start();
        new Thread(buyTicket,"黄牛").start();
    }
}
class BuyTicket implements Runnable{
    boolean flag = true;//外部停止标志
    private int ticket = 10;

    @Override
    public void run() {
        while (flag){
            buy();
        }
    }

    //买票
    //synchronized给方法加锁
    private synchronized void buy(){
        if(ticket<=0){
            flag = false;
            System.out.println("卖完了哦");
            return;
        }
        System.out.println(Thread.currentThread().getName()+"拿到第"+ticket--+"张票");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

}

在该例子中,同步锁锁定的是this也就是实例化的对象.当main方法中开启了多个线程 ---我,你,黄牛,每一个线程都需要拿到buyTicket对象才能继续运行,否则等待.

package syn;

public class UnsafeBank {
    public static void main(String[] args) {
        Account account = new Account(1000, "基金");
        Drawing you = new Drawing(account,50,"你");
        Drawing girl = new Drawing(account,100,"妻子");
        //System.out.println( account.money);
        you.start();
        girl.start();
    }
}

//账户,相当于银行卡
class Account{
    int money;//你的账户里有多少钱
    String name;

    public Account(int money, String name) {
        this.money = money;
        this.name = name;
    }
}

//银行,人可以通过银行操控银行卡
class Drawing extends Thread{
    Account account;//你的账户,这里的账户是内部类(复制外部类的值而已,不改变外部类)
    int drawingMoney;//取了多少钱
    int nowMoney;//你手里现在还有多少钱

    public Drawing(Account account, int drawingMoney, String name) {
        super(name);
        this.account = account;
        this.drawingMoney = drawingMoney;
    }

    @Override
    public void run() {//取钱
        synchronized (account){//同步锁锁的是account对象,account只有一个
            if(account.money-drawingMoney<0){
                System.out.println(Thread.currentThread().getName()+"余额不足,无法取款");
                return;
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            account.money = account.money-drawingMoney;//卡内的钱
            nowMoney = nowMoney+drawingMoney;//你手里的钱
            System.out.println(account.name+"余额为"+account.money);
            System.out.println(this.getName()+"手里的钱为"+nowMoney);
        }

    }
}

解析代码中

package syn;

import java.util.ArrayList;
import java.util.List;

public class UnsafeList {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            new Thread(()->{
                synchronized (list){//list中添加了多个线程,但list只有一个,线程需要锁定list才能执行造成每个线程都要排队挨个拿list再执行
                    list.add(Thread.currentThread().getName());
                }
            }).start();
        }
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(list.size());
    }
}

posted @ 2023-03-13 09:18  北极有熊ovo  阅读(36)  评论(0)    收藏  举报