Java--多线程--synchronized--同步

目录

synchronized--同步

练习一

练习二

练习三


synchronized--同步
练习一
package syn;
​
//不安全的买票
//线程不安全,有负数
public class UnsafeBuyTicket {
​
    public static void main(String[] args) {
        BuyTicket station = new BuyTicket();
​
        new Thread(station,"我").start();
        new Thread(station,"你").start();
        new Thread(station,"他").start();
    }
}
​
class BuyTicket implements Runnable{
​
    //票
    private int ticketNums = 10;
    boolean flag = true;  //外部停止方式
​
​
    @Override
    public void run() {
        //买票
        while (flag){
            try {
                buy();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
​
    }
    //sychronized 同步方法,锁的是this
    private synchronized void buy() throws InterruptedException {
        //判断是否有票
        if (ticketNums<=0){
            flag = false;
            return;
        }
​
        //模拟延时
​
        Thread.sleep(1000);
​
​
        //买票
        System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);
    }
}
//运行结果-1原因:
//每个线程在自已的工作内存交互,内存控制不当会造成数据不一致
练习二
package syn;
​
//不安全的取钱
//两个去银行取钱,账户
public class UnsafeBank {
    public static void main(String[] args) {
        //账户
        Account account = new Account(100,"结婚基金");
​
        Drawing you = new Drawing(account,50,"你");
        Drawing girlFriend = new Drawing(account,100,"女朋友");
​
        you.start();
        girlFriend.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;
​
    }
​
    //取钱
    //synchronized 默认锁的是this
    @Override
    public  void run() {
​
        //锁的对象就是变化的量,需要增删改的对象
        synchronized (account){
        //判断有没有钱
        if (account.money-drawingMoney<0){
            System.out.println(Thread.currentThread().getName()+"钱不够,取不了");
            return;
        }
        //sleep可以放大问题的发生性
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
​
        //卡内余额 = 余额 - 你取的钱
        account.money = account.money - drawingMoney;
        //你手里的钱
        nowMoney = nowMoney + drawingMoney;
​
        System.out.println(account.name+"余额为:"+account.money);
        //Thread.currentThread().getName() = this.getName()
        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<String>();
        for (int i = 0; i < 10000; i++) {
            new Thread(()->{
                synchronized (list){
                    list.add(Thread.currentThread().getName());
                }
            }).start();
            
        }
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(list.size());
    }
​
}