質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.83%

  • Java

    12870questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

以下のソースコードについて計算結果の数値は毎回?変わりますが、例えばどのような計算経路で25000という値が出てくるのかわかりません

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 142

peachmonga

score 1

初めて質問させていただきます。よろしくお願いします。
以下のjavaのソースコードについて、最初にbalanceに30000と入れてみて1000を5回入金、5回出金する場合、実行後に出力される数値は同じだったり異なったりしますが、例えば実行後に25000と出力された場合、Accountクラスの中のdiposit、withdrawの処理で具体的にtemp、balanceにどの様に値が入って25000と出力されているのでしょうか?

public class Account {
private long balance;

public long getBalance(){
return balance;
}

Account(long balance){
this.balance=balance;
}

void withdraw(long amount){
try{
Thread.sleep(200);
long temp = balance;
Thread.sleep(200);
temp -=amount;
Thread.sleep(200);
balance = temp;
}catch(InterruptedException e){
e.printStackTrace();
}
}
void deposit(long amount){
try{
Thread.sleep(200);
long temp = balance;
Thread.sleep(200);
temp +=amount;
Thread.sleep(200);
balance = temp;
}catch(InterruptedException e){
e.printStackTrace();
}
}
}

-----ここから入金のプログラムです-------

public class InATMThread extends Thread {
Account ac;

InATMThread(Account ac){
this.ac = ac;
}

public void run(){
for (int i = 0; i < 5; i++){
ac.deposit(1000);
System.out.println("1000円ふりこみました");
}
}
}

-----出金のプログラムです-----
public class OutATMThread extends Thread {
Account ac;

OutATMThread(Account ac){
this.ac = ac;
}

public void run(){
for(int i = 0; i < 5; i++){
ac.withdraw(1000);
System.out.println("1000円ひきだしました");
}
}
}

-----実行のプログラムです-----

public class UseATM {

public static void main(String[] args) {
// TODO 自動生成されたメソッド・スタブ
Account ac = new Account(30000);

InATMThread in = new InATMThread(ac);
OutATMThread out = new OutATMThread(ac);

in.start();
out.start();

try{
in.join();
out.join();
}catch(Exception e){
e.printStackTrace();
}
System.out.println("残高:"+ac.getBalance());
}

}

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+3

5回ではなく1回分だけ考えても参考になると思いますのでその前提で考えてみますと

          Thread-1         Thread-2
balance
30000      deposit          withdraw
          200ms sleep       200ms sleep
30000   ===>temp = 30000
        ====================>temp = 30000
          200ms sleep       200ms sleep
            temp = 31000     temp = 29000
          200ms sleep       200ms sleep
31000  <===tempの値をbalanceへcopy
29000  <=====================tempの値をbalanceへcopy


このように動いている場合balanceは一瞬だけ31000になり直後に29000になります。タイミングによっては逆に31000になる場合もあるということです。

このような奇妙な結果になる原因はbalanceの値をtempへコピーしてそれを計算して元へ戻すなら「更新操作の間、他のスレッドがbalanceにアクセスしないように排他制御をしなければならないのにそれをしていない」からです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/17 02:05

    早速の御回答ありがとうございます!
    スッキリ解りました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.83%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    java timerクラスについて

    javaについて勉強中です。 一定時間経過した後に、下の処理を実行させるような簡単なプログラムの作り方を、 教えていただけないでしょうか?  timerクラスを使えばいいみたいな

  • 解決済

    java 画像の表示

    コード import java.applet.Applet; import java.awt.*; public class sample extends Applet{    

  • 解決済

    時間をあける方法

    コード public class formal3 extends Applet{          public void paint(Graphics g){         

  • 解決済

    javaのclassをまとめたい

    質問内容 eclipseを使用してjavaのマルチスレッド(3つ)を作る課題をやっているんですが,現段階ではスレッドごとにクラスを作り処理を行っています。 最終的には一つのクラ

  • 解決済

    スレッドについて

    http://www.techscore.com/tech/Java/JavaSE/Thread/3/ ここのサイトでスレッドについて調べています。 複数のスレッドが同じオ

  • 解決済

    Javaのスレッドの対象インスタンスについて

    Javaのsynchronized修飾子の対象インスタンスについての質問です。 http://www.tohoho-web.com/java/thread.htm こちらの記事

  • 受付中

    textViewの表示に際してカウントアップさせたいのですが…

    Javaを学習し始めて3カ月ぐらいですが、いろいろなサイトやブログを見てみたのですが、よくわからなかったので今回投稿させていた抱きました。 ストップウォッチの制作しているのですが

  • 解決済

    スレッドの使い方について、口座システムを作りたい

    前提・実現したいこと Javaを用いて、二人(husbandとwife)が100円の出入金を繰り返すプログラムを2つのスレッドを使ってつくりたいのですが、「Thread[Thre

同じタグがついた質問を見る

  • Java

    12870questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • トップ
  • Javaに関する質問
  • 以下のソースコードについて計算結果の数値は毎回?変わりますが、例えばどのような計算経路で25000という値が出てくるのかわかりません