Day41

线程同步

synchronized

并发控制

在一个多线程的环境下,保证线程的安全性和准确性,同时还要提高它的性能。

并发:同个对象多个线程同时操作

线程不安全

1、12306取票会有不同的人抢到相同或者负数

package com.sxt.syn;

/**
 * 线程不安全 有相同和负数的情况
 */
public class UnsafeTest01 {
        public static void main(String[] args) {
            //一份资源
            UnsafeWeb12306 web = new UnsafeWeb12306();
            //多个代理
            new Thread(web,"码畜").start();
            new Thread(web,"码农").start();
            new Thread(web,"码磺").start();
        }
    }
 class UnsafeWeb12306 implements Runnable {
     //票数
     private int ticketNums = 10;
     private boolean flag=true;

     @Override
     public void run() {
         while (flag) {
             test();
         }
     }
     public void test(){
         if(ticketNums<0){
             flag=false;
             return;
         }
         //模拟网络延时
         try {
             Thread.sleep(200);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
         System.out.println(Thread.currentThread().getName()+"---->"+ticketNums--);
     }
 }

2、银行取钱

会出现账户余额负数的问题

加了判断依旧不能解决,这就是线程不安全

if (account.money-drawingMoney<0){
return;
}

package com.sxt.syn;

/**
 * 线程不安全:取钱
 */
public class UnsafeTest02 {
    public static void main(String[] args) {
        Account account = new Account(100,"结婚礼金");
        Drawing you = new Drawing(account,80,"可悲的你");
        Drawing wife = new Drawing(account,90,"happy的她");
        you.start();
        wife.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 packetTotal;//口袋钱的总数

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

    @Override
    public void run() {
        if (account.money-drawingMoney<0){
            return;
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        account.money-=drawingMoney;
        packetTotal+=drawingMoney;
        System.out.println(this.getName()+"----->账户余额为"+account.money);
        System.out.println(this.getName()+"----->口袋的钱为"+packetTotal);
    }
}
/**
可悲的你----->账户余额为-70
happy的她----->账户余额为-70
happy的她----->口袋的钱为90
可悲的你----->口袋的钱为80
*/

3、加入数据丢失(被覆盖)

都是线程不安全的表现

package com.sxt.syn;

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

/**
 * 线程不安全:操作容器
 */
public class UnsafeTest03 {
    public static void main(String[] args) {
        List<Object> list = new ArrayList<>();
        for (int i = 0; i <1000 ; i++) {
            new Thread(()->{
                list.add(Thread.currentThread().getName());
            }).start();
        }
        System.out.println(list.size());
    }
}
/**
993
*/

不是所有线程都要保证安全,只有我们要执行改的才需要保证线程安全,如果只需要读就不用

线程安全

1、等待池形成队列+2、锁机制

锁机制:synchronized

当一个线程获得对象的排它锁,独占资源,其他线程必须等待,使用后释放锁即可

一个线程持有锁会导致其他所有需要此锁的线程挂起:

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

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

synchronized关键字,它包括两种方法:synchronized方法和synchronized块

同步方法:public synchronized void method(int args){}

缺陷:若将一个大的方法声明为synchronized将会大大影响效率

package com.sxt.syn;

/**
 * 线程安全 :在并发时保证数据的准确性、效率尽可能高
 * synchronized
 * 1、同步方法
 * 2、同步块
 */
public class SynTest01 {
        public static void main(String[] args) {
            //一份资源
            SafeWeb12306 web = new SafeWeb12306();
            //多个代理
            new Thread(web,"码畜").start();
            new Thread(web,"码农").start();
            new Thread(web,"码磺").start();
        }
    }

class SafeWeb12306 implements Runnable {
    //票数
    private int ticketNums = 10;
    private boolean flag=true;

    @Override
    public void run() {
        while (flag) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            test();
        }
    }
    //线程安全 同步
    public synchronized void test(){
        if(ticketNums<=0){
            flag=false;
            return;
        }
        //模拟网络延时
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"---->"+ticketNums--);
    }
}

银行取钱:目标不对,锁定失败

package com.sxt.syn;

/**
 * 线程安全 :在并发时保证数据的准确性、效率尽可能高
 *  * synchronized
 *  * 1、同步方法
 *  * 2、同步块
 */
public class SynTest02 {
    public static void main(String[] args) {
        Account account = new Account(100,"结婚礼金");
        SafeDrawing you = new SafeDrawing(account,80,"可悲的你");
        SafeDrawing wife = new SafeDrawing(account,90,"happy的她");
        you.start();
        wife.start();
    }
}
//模拟提款机
class SafeDrawing extends Thread{
    Account account;//取钱的账户
    int drawingMoney;//取的钱数
    int packetTotal;//口袋钱的总数

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

    @Override
    public void run() {
        test();
    }
    //目标不对,锁定失败,这里不是锁this 应该锁 account
    public synchronized void test(){
        if (account.money-drawingMoney<=0){
            return;
        }
        try{
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        account.money-=drawingMoney;
        packetTotal+=drawingMoney;
        System.out.println(this.getName()+"----->账户余额为"+account.money);
        System.out.println(this.getName()+"----->口袋的钱为"+packetTotal);
    }
}

同步块:synchronized(具体的对象) 具体对象称之为同步监视器

方法中的块叫局部快

类中方法外的块叫构造快

在块上加个static叫静态块(先于构造快执行)

同步块在方法里

提款机取钱利用同步块确认线程安全

同步块:目标更明确

提高性能的代码
if (account.money<=0){
return;
}

package com.sxt.syn;

/**
 * 线程安全 :在并发时保证数据的准确性、效率尽可能高
 *  * synchronized
 *  * 1、同步方法
 *  * 2、同步块:目标更明确
 */
public class SynBlockTest01 {
    public static void main(String[] args) {
        Account account = new Account(100,"结婚礼金");
        SynDrawing you = new SynDrawing(account,80,"可悲的你");
        SynDrawing wife = new SynDrawing(account,90,"happy的她");
        you.start();
        wife.start();
    }
}

//模拟提款机 线程安全
class SynDrawing extends Thread{
    Account account;//取钱的账户
    int drawingMoney;//取的钱数
    int packetTotal;//口袋钱的总数

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

    @Override
    public void run() {
        test();
    }
    //目标锁定account
    public void test(){
        //提高性能的代码
        if (account.money<=0){
            return;
        }
        //同步块
        synchronized (account) {
            if (account.money - drawingMoney <0) {
                return;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            account.money -= drawingMoney;
            packetTotal += drawingMoney;
            System.out.println(this.getName() + "----->账户余额为" + account.money);
            System.out.println(this.getName() + "----->口袋的钱为" + packetTotal);
        }
    }
}

同步块确保容器线程安全

package com.sxt.syn;

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

/**
 * 线程安全:操作容器
 */
public class SynBlockTest02 {
    public static void main(String[] args) throws InterruptedException {
        List<Object> list = new ArrayList<>();
        for (int i = 0; i <1000 ; i++) {
            new Thread(()->{
                //同步块
                synchronized (list) {
                    list.add(Thread.currentThread().getName());
                }
            }).start();
        }
        Thread.sleep(10000);
        System.out.println(list.size());
    }
}
内容概要:本文详细介绍了基于滑模控制(SMC)和H∞控制相结合的方法应用于永磁直线同步电机(PMLSM)的鲁棒控制。首先阐述了PMLSM的基本数学模型及其物理意义,包括d-q坐标系下的电压方程和运动方程。随后解释了滑模控制的工作原理,重点在于如何构建滑模面并确保系统沿此面稳定运行。接着讨论了H∞控制的目标——即使在不确定条件下也能保持良好的性能表现。文中还提供了具体的Matlab代码实例,展示了如何利用Matlab控制系统工具箱进行H∞控制器的设计。最后给出了一段完整的Matlab程序框架,演示了两种控制方法的具体实现方式。 适合人群:从事电机控制领域的研究人员和技术人员,尤其是那些想要深入了解滑模控制和H∞控制理论及其在实际工程中应用的人士。 使用场景及目标:适用于需要提高永磁直线同步电机控制系统抗干扰能力和鲁棒性的场合,如工业自动化生产线、精密加工设备等。通过学习本篇文章提供的理论知识和编程技巧,读者能够掌握这两种先进控制策略的应用方法,从而提升自身解决复杂控制问题的能力。 其他说明:文中所涉及的内容不仅限于理论讲解,还包括了大量的实战经验分享,有助于读者快速上手并在实践中不断改进自己的设计方案。同时鼓励读者积极尝试不同的参数配置,以便找到最适合特定应用场景的最佳解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值