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);
} } }
}

运行结果

Java之线程同步练习的更多相关文章

  1. Java 并发 线程同步

    Java 并发 线程同步 @author ixenos 同步 1.异步线程本身包含了执行时需要的数据和方法,不需要外部提供的资源和方法,在执行时也不关心与其并发执行的其他线程的状态和行为 2.然而,大 ...

  2. Java中线程同步的理解 - 其实应该叫做Java线程排队

    Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可 ...

  3. java中线程同步的理解(非常通俗易懂)

    转载至:https://blog.csdn.net/u012179540/article/details/40685207 Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运 ...

  4. JAVA中线程同步的方法(7种)汇总

    同步的方法: 一.同步方法 即有synchronized关键字修饰的方法. 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法.在调用该方法前,需要获得内置锁,否则就 ...

  5. Java多线程——线程同步

    在之前,已经学习到了线程的创建和状态控制,但是每个线程之间几乎都没有什么太大的联系.可是有的时候,可能存在多个线程多同一个数据进行操作,这样,可能就会引用各种奇怪的问题.现在就来学习多线程对数据访问的 ...

  6. Java并发——线程同步Volatile与Synchronized详解

    0. 前言 转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52370068 面试时很可能遇到这样一个问题:使用volatile修饰in ...

  7. Java中线程同步的方法

    同步方法 即有synchronized关键字修饰的方法. 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法.在调用该方法前,需要获得内置锁,否则就处于阻塞状态. 注 ...

  8. Java中线程同步的理解

    我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可能和其他线程共享一些资源, ...

  9. Java多线程 - 线程同步

    多线程操作同一个对象时,容易引发线程安全问题.为了解决线程安全问题,Java多线程引入了同步监视器. 同步代码块 同步代码块语法格式如下: synchronized(obj){ //此处的代码即为同步 ...

  10. JAVA多线程线程同步问题

    线程同步 在多线程的编程环境下,可能看着没有问题的代码在运行几千上万或者更多次后,出现了一些看着很奇怪的问题,出现这样的问题的原因就是可能会有两个或者更多个线程进入了同一块业务处理代码中导致了判断失效 ...

随机推荐

  1. spring之bean

    Bean的基本配置 id属性 id属性确定bean的唯一标识符,容器对bean的管理,访问,以及该bean的依赖关系,都通过该属性来完成.bean的id属性在Spring容器中应该是唯一的. clas ...

  2. node express安装

    我们现在全局安装只需要安装这个命令行工具就可以,指令如下: npm install -g express-generator 这时我们就着手安装express框架,指令如下: express blog ...

  3. Unity 脚本中各种[XXX]的用法

    1.[SerializeField]在Inspector中显示非public属性,并且序列化:若写在public修饰的字段前,相当于没写,Unity会自动为Public变量做序列化,序列化的意思是说再 ...

  4. CSS浮动专题!

    在css中,浮动问题可能是很多刚入门的小白比较头疼的问题. 1,首先先来介绍一下两种浮动类型:左浮动和右浮动 1) float:left;左浮动,后面的内容会流向对象的右侧 2) float:righ ...

  5. CPP笔记_泛型编程简单总结

    本篇是基于<Essential C++>第三章泛型编程风格的一个简单总结 1 Iterator vector<string>::iterator  表明此iterator是位于 ...

  6. JavaEE开发之SpringMVC中的静态资源映射及服务器推送技术

    在上篇博客中,我们聊了<JavaEE开发之SpringMVC中的自定义拦截器及异常处理>.本篇博客我们继续的来聊SpringMVC的东西,下方我们将会聊到js.css这些静态文件的加载配置 ...

  7. 永久设置mysql中文乱码问题

    1.进入mysql的命令窗口 输入 show variables like '%char%'; 查看当前编码是否为UTF-8 2.在上述命令的结果中我们可以看到Wamp的安装目录,找到这一目录,在里面 ...

  8. bzoj4785 [Zjoi2017]树状数组

    Description 漆黑的晚上,九条可怜躺在床上辗转反侧.难以入眠的她想起了若干年前她的一次悲惨的OI 比赛经历.那是一道基础的树状数组题.给出一个长度为 n 的数组 A,初始值都为 0,接下来进 ...

  9. 【算法系列学习】Dijkstra单源最短路 [kuangbin带你飞]专题四 最短路练习 A - Til the Cows Come Home

    https://vjudge.net/contest/66569#problem/A http://blog.csdn.net/wangjian8006/article/details/7871889 ...

  10. 在Mvc中进行异步请求是出现(没有为该对象定义无参数的构造函数)

    解决办法就是给相应的类添加无参数的构造函数: