java 1000个线程的抢票程序(原理)对类变量的同步

该程序演示了一个基于Java的多线程票务系统,其中类变量`p`表示票号,需要保证线程安全。通过在`Sv`类的`run`方法中使用`synchronized`关键字同步对`App.o`的访问,确保同一时间只有一个线程可以访问并修改票号。系统使用`ExecutorService`管理1000个线程,模拟1000个购票者通过Socket连接进行购票操作。
摘要由CSDN通过智能技术生成

本程序的难点:对类变量的同步,最简单的方法:要同步的变量属于哪个类,就对哪个类的实例加锁。

理清几种变量:类变量,类静态变量,局部变量,共享变量。

服务端:类变量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);
        }

    }
}

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值