本程序的难点:对类变量的同步,最简单的方法:要同步的变量属于哪个类,就对哪个类的实例加锁。
理清几种变量:类变量,类静态变量,局部变量,共享变量。
服务端:类变量p相当于票号,必须是唯一的,对它必须是同步的,一个线程访问P时,另外999个线程必须阻塞等待。
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class App {
static int p=1000; //App类对象,必须对App类实例加锁来同步p
static Object o=new Object(); //App类的所以对象的锁
public static void main(String[] args) throws IOException {
ExecutorService es = Executors.newFixedThreadPool(1000);
ServerSocket serverSocket = new ServerSocket(6000);
for(int k=0;k<1000;k++){
Socket socket = serverSocket.accept();
Sv sv = new Sv(socket);
es.submit(sv);
}
es.shutdown();
}
}
class Sv implements Runnable{
Socket socket;
Sv(Socket socket){
this.socket=socket;
}
public void run() {
InputStream inputStream= null;
try {
inputStream = socket.getInputStream();
OutputStream outputStream=socket.getOutputStream();
ObjectInputStream objectInputStream=new ObjectInputStream(inputStream);
ObjectOutputStream objectOutputStream=new ObjectOutputStream(outputStream);
int id=objectInputStream.readInt();
synchronized (App.o) { //重点:App.o 代表对App的实例加锁,凡是App类的实例必须执行这个锁
objectOutputStream.writeInt(App.p);
objectOutputStream.flush();
System.out.println(String.valueOf(id)+": "+App.p);
App.p--;
}
socket.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
客户端:1000个请求socket,相当于1000 个购票者。
import java.io.*;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test{
public static void main(String[] args) throws IOException {
ExecutorService es=Executors.newFixedThreadPool(1000);
for(int h=0;h<1000;h++){
Sp s=new Sp();
es.submit(s);
}
es.shutdown();
}
}
class Sp implements Runnable{
public void run() {
Socket socket= null;
try {
socket = new Socket("127.0.0.1",6000);
OutputStream outputStream=socket.getOutputStream();
InputStream inputStream=socket.getInputStream();
ObjectOutputStream objectOutputStream=new ObjectOutputStream(outputStream);
ObjectInputStream objectInputStream=new ObjectInputStream(inputStream);
int id= (int) Thread.currentThread().getId();
objectOutputStream.writeInt(id);
objectOutputStream.flush();
int sp=objectInputStream.readInt();
System.out.println("客户"+id+": "+sp);
socket.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}