Java之线程同步练习
生活随笔
收集整理的這篇文章主要介紹了
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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic String toString() {return "Card1 [money=" + money + "]";}public synchronized void save(){if(flag == false){// 存了還沒取 存錢等著try {this.wait();// 掛起來的是 存錢的線程} catch (InterruptedException e) {// TODO Auto-generated catch blocke.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 blocke.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;}@Overridepublic 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;}@Overridepublic void run() {// -499~500for (int i = 0; i < 20; i++) {synchronized (card) {int a = (int)(Math.random()*1000+1)-500;card.add(a);}}} }運行結果
總結
以上是生活随笔為你收集整理的Java之线程同步练习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 欢迎使用Markdown编辑器写博客
- 下一篇: Java之【线程通信】--标志位练习