zoukankan      html  css  js  c++  java
  • Thread 多线程 同步

    当多个线程,访问同一个对象,调用同一个方法或访问同一个对象时。有时,必须保证访问的同步性。
    比如,一个银行信用卡账户具有5000元的信用额度。用户除具有一张主卡外,还办有多张子卡。这些卡的累计消费金额,不能超过信用卡的额度。当用户在多个POS机上请求消费时,如果不对请求操作进行操作,可能会造成错误。

    /**
    * 同步模拟银行信用卡取款
    */
    public class Tongbu implements Runnable{
    private int money;
    private int get;

    public int getMoney() {
    return money;
    }
    public void setGet(int get) {
    this.get = get;
    }
    public Tongbu(){
    this.money = 5000;
    }

    public synchronized void get() {
    if (this.money >= get) {
    /*此处休眠,以摸拟,假使在此时,多个请求线程之间进行了切换。一个线程让出处理器。*/
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    }
    this.money -= get;
    System.out.println("取款成功。" + get);
    } else {
    System.out.println("余额不足。");
    }
    }
    @Override
    public void run() {
    if (get>0) get();
    }

    public static void main(String[] args){
    Tongbu t1=new Tongbu();
    Thread T=new Thread(t1);
    Thread T1=new Thread(t1);
    t1.setGet(3000);
    T.start();
    t1.setGet(3000);
    T1.start();
    try {
    Thread.sleep(2000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("余额: "+t1.getMoney());

    }
    }
    以上例子若是t1取款3000,t1再取款2000就会两次都取款2000,第一次取的3000就少了1000.这是因为get是共享的,会覆盖。
    以下是改进例子:
    **
    * 同步模拟银行信用卡取款
    */
    public class Tongbu extends Thread{
    private creditCard card;
    private Integer get;

    public Integer getGet() {
    return get;
    }

    public void setGet(Integer get) {
    this.get = get;
    }

    public Tongbu(creditCard card){
    this.card = card;
    }

    public void get() {
    if ( card.getMoney()>= get) {
    /*此处休眠,以摸拟,假使在此时,多个请求线程之间进行了切换。一个线程让出处理器。*/
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    }
    card.setMoney(card.getMoney()-get);
    System.out.println("取款成功。" + get);
    } else {
    System.out.println("余额不足。");
    }
    }
    @Override
    public void run() {
    if (get>0) get();
    }

    public static void main(String[] args){
    creditCard card=new creditCard(5000);
    Tongbu t1=new Tongbu(card);
    Tongbu t2=new Tongbu(card);
    t1.setGet(3000);
    t1.start();
    System.out.println("余额: "+card.getMoney());
    t2.setGet(1000);
    t2.start();
    try {
    Thread.sleep(3000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("余额: "+card.getMoney());

    }
    }
    class creditCard{
    private int money;

    public creditCard(int money) {
    this.money = money;
    }

    public int getMoney() {
    return money;
    }

    public void setMoney(int money) {
    this.money = money;
    }

    }
  • 相关阅读:
    VS Code的使用
    跨平台C++ IDE
    windows CMakeLists.txt
    Windows引用opencv静态库
    【wpf】WPF程序处理多线程的两种方式
    【c#】System.Reflection.TargetInvocationException 调用的目标发生了异常/System.Threading.ThreadAbortException:正在中止线程
    【WinForm】Dev ProgressBarControl 使用汇总
    【WPF】UserControl用户控件怎么添加到Window窗体中
    【WPF】WPF无边框、窗体初始化位置与可拖拽窗体的解决方案
    【c#】未加载mscorlib.pdb/System.Reflection.TargetParameterCountException 未经处理的异常在mscorlib.dll中发生/参数计数不匹配
  • 原文地址:https://www.cnblogs.com/feipengting/p/7543394.html
Copyright © 2011-2022 走看看