14、线程同步机制

线程同步机制

1、同一个进程的多个线程共享同一块存储空间,带来了方便,也有冲突,为了保证数据在方法中被访问的正确性,在访问时加锁机制,synchronized,当一个线程获得对象的排他锁,独占资源,其他线程必须等待使用后释放;

问题:

1、一个线程持有锁,会导致其他的需要此锁的线程挂起;

2、多线程竞争下,加锁,释放,会导致上下文切换,和调度延时,引起性能问题;

3、如果一个优先级高的线程,等待一个优先级低的线程释放锁,会导致优先级倒置,引起性能问题;

 

同步块:synchronized(obj){}

obj:同步监视器

obj可以时任何对象,但是推荐使用共享资源作为监视器

同步方法中无需指定同步监视器,因为同步方法的同步监视器就是this,这个对象的本身,或者是class,

同步监视器的执行过程:

1、第一个线程访问,锁定同步监视器,执行其中代码

2、第二个线程访问,发现同步监视器被锁定,无法访问

3、第一个线程访问完毕后,解锁同步监视器

4、第二个线程访问,发现同步监视器没有锁,然后锁定访问

 

线程同步安全

 

package com.syn;
public class UnsafeBank {
    public static void main(String[] args) {
        Account account = new Account(8000,"ICBC_Bank");
        Drawring accountDrawrer1 = new Drawring(account,5000,"liwang1");
        Drawring accountDrawrer2 = new Drawring(account,5000,"liwang2");
        accountDrawrer1.start();
        accountDrawrer2.start();
    }
}
//账户类
class Account{
    int accountBalance;//余额
    String AccountName;//卡名
    //构造方法,类名一致
    public Account(int accountBalance, String AccountName) {
        this.accountBalance = accountBalance;
        this.AccountName = AccountName;
    }
}
//银行取钱
class Drawring extends Thread{
    Account accountinfo;//Account类定义账户信息
    int drawringmoney;//取钱金额
    int nowmoney;//现在拥有的钱
    private Object Account;
    //构造方法
    public Drawring(Account account, int drawringmoney, String name) {
        super(name);
        this.accountinfo = account;
        this.drawringmoney = drawringmoney;
    }
    //重写run方法
    @Override
    public void run() {
        //同步代码块
        synchronized (accountinfo){
            //取钱
            if(accountinfo.accountBalance-drawringmoney<0){
                //输出信息
                System.out.println(Thread.currentThread().getName()+":余额不足");
                return;
            }
            try{
                Thread.sleep(1000);
            }catch (Exception e){
                e.printStackTrace();
            }
            //卡内余额
            accountinfo.accountBalance=accountinfo.accountBalance-drawringmoney;
            //拥有余额
            nowmoney=nowmoney+drawringmoney;
            //打印账户余额
            System.out.println(accountinfo+" 余额:"+accountinfo.accountBalance);
            //打印拥有的钱
            //Thread.currentThread().getName() = this.getName();
            System.out.println(this.getName()+"拥有的钱:"+nowmoney);
        }
        }
}

  

package com.syn;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class safeList {
    public static void main(String[] args) {
        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
        //List<String> list = new ArrayList<String>();
        for (int i=0;i<10000;i++){
            new Thread(()->{
                list.add(Thread.currentThread().getName());
            }).start(); }
        try{
            Thread.sleep(2000);
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println(list.size());
    }
}

  

 

posted @ 2022-07-24 16:45  颓废且努力奋斗的人  阅读(22)  评论(0编辑  收藏  举报