1、假设一个银行的ATM机,它可以允许用户存款也可以取款。现在一个账户上有存款200元,用户A和用户B都拥有在这个账户上存款和取款的权利。用户A将存入100元,而用户B将取出50元,那么最后账户的存款应是250元。实际操作过程如下:
(1) 先进行A的存款操作:
- 得到账户的存款数额200,耗时2s。
- 将账户数额增加100,耗时忽略不计
- 将新生成的账户结果300返回到ATM机的服务器上,耗时2s
(2) 再进行B的取款操作: - 得到增加后账户存款数额300,耗时2s。
- 判断取款额是否小于账户余额,若是,则将账户数额减少50,否则抛出异常信息,耗时忽略不计。
- 将新生成的账户结果250返回到ATM机的服务器上,耗时2s。
请根据以上要求,将A的操作和B的操作分别用线程来表示,编写一个Java程序实现该功能。
class ATM {
private float accountBalance;
public ATM(float money){
accountBalance=money;
}
public synchronized float getAccountBalance(){
try{
Thread.sleep(2000);
}catch(Exception e){ }
return accountBalance;
}
public synchronized void deposit(float money){
accountBalance=accountBalance+money;
}
public synchronized void drawMoney(float money) throws Exception{
if(accountBalance<money){
throw new Exception("Current accountBalance is not enough!");
}
accountBalance=accountBalance-money;
}
}
class UserA extends Thread{
private ATM atm;
private float money;
public UserA(ATM a,float m){
atm=a;
money=m;
}
public void run(){
System.out.println(atm.getAccountBalance());
System.out.println("Depositing "+money);
try{
atm.deposit(money);
}
catch(Exception e){ }
System.out.println("current Balance is "+atm.getAccountBalance());
}
}
class UserB extends Thread{
private ATM atm;
private float money;
public UserB(ATM a,float m){
atm=a;
money=m;
}
public void run(){
System.out.println(atm.getAccountBalance());
System.out.println("Drawing money: "+money);
try{
atm.drawMoney(money);
}
catch(Exception e){
System.out.println(e.getMessage());
}
System.out.println("current Balance is "+atm.getAccountBalance());
}
}
class TestATM{
public static void main(String []args){
ATM a=new ATM(200);
UserA userA=new UserA(a,100);
UserB userB=new UserB(a,50);
userA.start();
try{
userA.join();
}catch(Exception e){ }
userB.start();
}
}
2、用Java编写一个服务器端的程序Server.java,该程序在8000端口监听客户端的请求,如果与客户端连接后,收到客户端发送的数据不是字符串“bye”,则在服务器端打印客户端发来的数据,并向客户端回送一条从键盘输入的信息,若客户端发来的数据是字符串“bye”,则关闭服务器端程序。
Socket 客户端实例
如下的 GreetingClient 是一个客户端程序,该程序通过 socket 连接到服务器并发送一个请求,然后等待一个响应。
import java.net.*;
import java.io.*;
public class GreetingClient
{
public static void main(String [] args)
{
String serverName = args[0];
int port = Integer.parseInt(args[1]);
try
{
System.out.println("Connecting to " + serverName
+ " on port " + port);
Socket client = new Socket(serverName, port);
System.out.println("Just connected to "
+ client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out =
new DataOutputStream(outToServer);
out.writeUTF("Hello from "
+ client.getLocalSocketAddress());
InputStream inFromServer = client.getInputStream();
DataInputStream in =
new DataInputStream(inFromServer);
System.out.println("Server says " + in.readUTF());
client.close();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
Socket 服务端实例
如下的GreetingServer 程序是一个服务器端应用程序,使用 Socket 来监听一个指定的端口。
import java.net.*;
import java.io.*;
public class GreetingServer extends Thread
{
private ServerSocket serverSocket;
public GreetingServer(int port) throws IOException
{
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(10000);
}
public void run()
{
while(true)
{
try
{
System.out.println("Waiting for client on port " +
serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Just connected to "
+ server.getRemoteSocketAddress());
DataInputStream in =
new DataInputStream(server.getInputStream());
System.out.println(in.readUTF());
DataOutputStream out =
new DataOutputStream(server.getOutputStream());
out.writeUTF("Thank you for connecting to "
+ server.getLocalSocketAddress() + "\nGoodbye!");
server.close();
}catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
break;
}catch(IOException e)
{
e.printStackTrace();
break;
}
}
}
public static void main(String [] args)
{
int port = Integer.parseInt(args[0]);
try
{
Thread t = new GreetingServer(port);
t.start();
}catch(IOException e)
{
e.printStackTrace();
}
}
}