2012-12-02 25 views
1

我是Java新手,想了解同步是如何工作的。所以我創建了一個Plane Reservation System,我可以模擬多個用戶嘗試預訂並使用Synchromization來獲取正確的輸出。Java - 多用戶應用程序中的同步

現在,它的工作原理,我想這是如何在現實世界中的作品。例如,讓我們說應用程序是建立在Swing上的,這是一個多用戶應用程序。爲了簡單起見,我們假設只有兩架飛機'AAA'和'BBB'。該應用程序可以安裝在售票員代理人的計算機,機場的售貨亭以及不同旅行社的計算機中,並且他們都可以訪問相同的數據庫。

在這種情況下,每個用戶/計算機都有自己的Reserve類,Transaction類和Plane類的實例。所以Transaction類中只有一個線程/請求,並且沒有同步。

我的問題是,像這個Reservation系統這樣的多用戶應用程序將如何設計/實現,以便所有用戶都訪問Transacion類的一個實例,以便可以進行同步。你也可以看看這個問題,我怎樣才能建立不同計算機上不同玩家玩的多用戶遊戲。再舉一個例子,銀行系統可以在ATM和櫃員機上運行應用程序時進行存款,取款和轉賬。

///////////////////////////////

Reserve.java --->項點由用戶

/////////////////////////////

import java.io.IOException; 

public class Reserve { 

static int queryseatsavailableinx; 
static int queryseatsavailableiny; 

static 
{ 
    seats s = null; 
    try { 
     s = new seats(); 
    } catch (IOException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 
    try { 
     queryseatsavailableinx = s.getseatsinplanex("AAA"); 
     queryseatsavailableiny = s.getseatsinplanex("BBB"); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

static final Plane x1 = new Plane("AAA", 001, queryseatsavailableinx); 
static final Plane y1 = new Plane("BBB", 002, queryseatsavailableiny); 
static final Transaction trans = new Transaction(); 

public static void main(String[] args) throws InterruptedException { 

    Thread t1 = new Thread(new Runnable() { 

     public void run() { 
      trans.getPlaneInfo(x1); 
     } 
    }); 

    Thread t2 = new Thread(new Runnable() { 

     public void run() { 
      //trans.getPlaneInfo(x1); 
      trans.reserveSeats(x1,3); 
     } 
    }); 

    Thread t3 = new Thread(new Runnable() { 

     public void run() { 
      //trans.getPlaneInfo(y1); 
      trans.reserveSeats(y1,8); 
     } 
    }); 

    Thread t4 = new Thread(new Runnable() { 

     public void run() { 
      //trans.getPlaneInfo(x1); 
      trans.reserveSeats(x1,2); 
     } 
    }); 

    t1.start(); 
    t2.start(); 
    t3.start(); 
    t4.start(); 

    t1.join(); 
    t2.join(); 
    t3.join(); 
    t4.join(); 
} 

} 

由每個請求//// ///////////////////////////

Transaction.java --->實際交易發生在這裏

/////////////////////////////

public class Transaction { 

public void getPlaneInfo(Plane x){ 
    synchronized(this){ 
     int number = x.getSeatCapacity(); 
     String planename=x.getPlaneName(); 
     System.out.printf("The number of seats in plane %s is %d\n",planename,number); 
    } 

} 

public void reserveSeats(Plane x, int seatstobereserved) { 
    synchronized(this){ 
    x.updateSeatCapacity(seatstobereserved); 
    } 
    } 
} 

//////////// ///////////////////

Plane.java --->的有關飛機

信息//////////// /////////////////

final public class Plane { 

private String planename = null; 
private int planeid = 0; 
private int availableseatcapacity = 0; 

Plane(String planename, int planeid, int seatcapacity) { 
    this.planename = planename; 
    this.planeid = planeid; 
    this.availableseatcapacity = seatcapacity; 
} 

public String getPlaneName() { 
    return planename; 
} 

public int getPlaneId() { 
    return planeid; 
} 

public int getSeatCapacity() { 
    return availableseatcapacity; 
} 

public void updateSeatCapacity(int reservedseats) { 
    availableseatcapacity -= reservedseats; 
    System.out.printf("\n%d Seats successfully reserved and remaining seats " + 
      "in the plane %s are %d\n",reservedseats, planename,availableseatcapacity); 

} 

} 

//////////////////////// /////

Seats.java --->爲了模擬用戶每次發出請求時,從一個公共數據源/數據庫中檢索'可用位置數'。 /////////////////////////////

import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.EOFException; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 

final public class seats { 

seats() throws IOException { 
    DataOutputStream di1 = new DataOutputStream(new FileOutputStream(
      "\\PlaneReservation\\bin\\a.bin")); 
    DataOutputStream di2 = new DataOutputStream(new FileOutputStream(
      "\\PlaneReservation\\bin\\b.bin")); 

    di1.writeInt(300); 
    di2.writeInt(200); 
    di1.flush(); 
    di2.flush(); 
    di1.close(); 
    di2.close(); 
} 

public int getseatsinplanex(String s) throws IOException { 
    if (s.equals("AAA")) { 
     FileInputStream fis1 = new FileInputStream("\\PlaneReservation\\bin\\a.bin"); 
     DataInputStream dis1 = new DataInputStream(fis1); 
     int number = 0; 
     boolean eof = false; 
     while (!eof) { 
      try { 
       number = dis1.readInt(); 
      // System.out.println(number); 
      } catch (EOFException eofx) { 
       eof = true; 
       dis1.close(); 
      } 
     } 
     return number; 
    } else if (s.equals("BBB")) { 
     FileInputStream fis2 = new FileInputStream("\\PlaneReservation\\bin\\b.bin"); 
     DataInputStream dis2 = new DataInputStream(fis2); 
     int number = 0; 
     boolean eof = false; 
     while (!eof) { 
      try { 
       number = dis2.readInt(); 
       //System.out.println(number); 
      } catch (EOFException eofx) { 
       eof = true; 
       dis2.close(); 
      } 
     } 
     return number; 
    } 
    return 0; 
} 
} 
+4

http://sscce.org/ – dantuch

回答

2

讓人難以置信的是,你會使所有的Transaction的方法​​:這會讓你互相排斥。

但是,實際上,沒有一個系統就是這樣設計的。服務器端應用程序不是建模爲單個同步對象。相反,持久化狀態保存在支持ACID事務(原子,併發,隔離和持久)的關係數據庫中,並且對象的等效對象是無需在Java級別同步的無狀態單例對象。這樣的對象將被稱爲服務bean。它通常會在一個Dependency Injection容器(例如Spring)中創建,並且它將連接到一堆其他對象,如DAO(數據訪問對象),該對象又將實現與一個數據庫。依賴注入容器可以很容易地聲明性地構建互連對象的複雜圖形。典型的企業應用程序(如航空公司的預訂系統)至少包含數十個服務bean和更多的DAO,後者可連接到各種後端系統。

+0

我不知道春天,所以請原諒我的天真。那麼這是否意味着用戶會得到一個提供請求交易的服務bean?服務bean將如何確保它們都處理正確的數據。例如:三個服務bean顯示3個用戶,只有最後5個可用的座位。然後,所有3個用戶都同時保留最後5個席位? – user547453

+0

客戶端API有多種選擇,其中一種是實現服務bean接口的代理bean(只有當客戶端也是用Java實現時,這是一個選項)。就併發性而言,最終結果將始終如一,沒有超額預訂:一個客戶將獲得票據,而其他客戶將被通知票據出售。 –

2

要麼

a)您在依靠存儲在數據庫程序(確保原子性)來執行操作。

b)你只有一個實例(一個服務器)來保存關鍵部分。客戶端執行請求,服務器通知是否有可用的席位(操作成功)或沒有(操作失敗)。

真實世界的操作將主要是b,它可以使用a。

+2

無論如何,dantuch是對的。這個問題會更適合程序員.stackexchange.com,因爲它與你的代碼無關,而更多的是與描述/一般想法相關。 – SJuan76

+1

謝謝SJuan76 ...您的回答確實幫助我澄清了多用戶應用程序需要在分佈式環境中運行的概念。當我在Java中學習同步時,我遇到了類似於國際象棋遊戲的例子,其中2個線程代表2個玩家,但我缺少的主要觀點是程序在一臺計算機上運行,​​2個用戶可以玩。所以兩位玩家都看到相同的數據。 – user547453

相關問題