Java之线程同步练习

1.有一张银行卡:*属性:name,money(账户余额)*

多线程操作同一张银行卡:
金额:x(每次存钱取钱的数额,取钱时x为负数,存钱时x为整数)

定义一个add方法:用于存取钱,参数为x,即每次取或存的金额

add(int x){
判断x的正负
要么存,要么取
显示余额
}

多线程实现可以存钱也可以取钱,保证线程的安全.

分析:

线程安全是指保证进入执行状态的线程能将当次行为执行完成,即实现同步

金额是后台输入的,或直接使用随机数解决

代码:

方法一:直接操作,以及后台输入金额

package Homework;

import java.util.Scanner;

public class Test1 {
    public static void main(String[] args) {
        Card card=new Card("中国银行卡",0);
        MyThread thread=new MyThread(card);
        MyThread thread2=new MyThread(card);
        MyThread thread3=new MyThread(card);
        thread.start();
        thread2.start();
        thread3.start();
    }
}
//银行卡类
class Card{
    private String name;
    private int money;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getMoney() {
        return money;
    }
    public void setMoney(int money) {
        this.money = money;
    }
    @Override
    public String toString() {
        return "Card [name=" + name + ", money=" + money + "]";
    }
    public Card(String name, int money) {
        super();
        this.name = name;
        this.money = money;
    }
    public Card() {
        super();
    }

//定义的add方法,操作账户进行存取钱
    public synchronized void add(int num){
        int money1=getMoney();
        setMoney(money1+num);
        if(num>0){
            System.out.println(Thread.currentThread().getName()+"【存】了"+num+"元,当前"+getName()+"余额为:"+getMoney());
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else {
            System.out.println(Thread.currentThread().getName()+"【取】了"+(-num)+"元,当前"+getName()+"余额为:"+getMoney());
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

//线程
class MyThread extends Thread{
    Card card;
    public MyThread(Card card){
        this.card=card;
    }
    @Override
    public void run() {
        Scanner input=new Scanner(System.in);
        while(true){
            synchronized (card) {
                System.out.println("请输入金额:");
                int num=input.nextInt();
                card.add(num);
            }
        }
    }
}

运行结果:

这里写图片描述

方法二:使用标志位,以及随机数

银行卡类:

package com.qf.demo;

public class Card1 {

    private int money = 0;

    boolean flag = true; //true 取了钱,但是还没存     取钱的等着   存钱的执行
                        // false   存了钱了,但是没取          存钱的等着   取钱的执行
    public Card1(int money) {
        super();
        this.money = money;
    }

    public Card1() {
        super();
    }

    public int getMoney() {
        return money;
    }

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

    @Override
    public String toString() {
        return "Card1 [money=" + money + "]";
    }

    public synchronized void save(){
        if(flag == false){// 存了还没取   存钱等着
            try {
                this.wait();// 挂起来的是  存钱的线程
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        // 就证明是true 取了还没存
        this.money+=1000;
        System.out.println("存了1000,还剩下"+this.money);
        // 已经存完钱了
        flag = false;
        this.notify();
    }

    public synchronized void get(){
        if(flag==true){// true   取了还没存     取钱的等着   存钱的 执行
            try {
                this.wait();// 挂起来的是取钱的线程
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        // 没进去wait 就证明flag 是false     存了还没取
        this.money = this.money-1000;
        System.out.println("取了1000,还剩"+this.money);
        // 取完钱了
        flag = true;
        this.notify();
    }
}

测试类与子线程:

package com.qf.demo;

public class Test {

    public static void main(String[] args) {
        Card card = new Card();
        MyThread thread = new MyThread(card);
        MyThread thread2 = new MyThread(card);

        thread.start();
        thread2.start();

    }
}

class Card{
    private String name;
    private int money ;
    public Card(String name, int money) {
        super();
        this.name = name;
        this.money = money;
    }
    public Card() {
        super();
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getMoney() {
        return money;
    }
    public void setMoney(int money) {
        this.money = money;
    }
    @Override
    public String toString() {
        return "Card [name=" + name + ", money=" + money + "]";
    }
    // 最小作用域最强原则: 局部变量和 全局变变量同名的时候,在这个方法中优先使用的是  局部变量
    public void add(int money){
        if(money>0){
            this.money = this.money+money;
            System.out.println(Thread.currentThread().getName()+"存了"+money+"余额为"+this.money);
        }else {
            this.money = this.money+money;
            System.out.println(Thread.currentThread().getName()+"取了"+(-money)+"余额为"+this.money);
        }
    }
}

class MyThread extends Thread{
    Card card;

    public MyThread(Card card) {
        this.card = card;
    }

    @Override
    public void run() {
        // -499~500
        for (int i = 0; i < 20; i++) {
            synchronized (card) {
                int a = (int)(Math.random()*1000+1)-500;
                card.add(a);
            }

        }

    }
}

运行结果

这里写图片描述

原文地址:https://www.cnblogs.com/TCB-Java/p/6797617.html