java - 修改和访问线程类之外的值

标签 java multithreading oop arraylist

我是 OOP 新手,尤其是 Java。因此,我很难从两个类中访问和删除 ArrayList 中的值。

我有一个 Counter 类,其中只有一个 ArrayList,我必须从两个不同的类中调用它。

public class Counter12 {
   public static ArrayList<String> clientsStorage = new ArrayList<String>();
}

Server12

public class Server12 {
//public static int counter = 0;
public static void main(String[] argv) throws Exception {

    //Create a server socket, bounds to a specified port
    ServerSocket serverSocket = new ServerSocket(5016);
    System.out.println("Server started");
    //int counter = 0;
    //ArrayList<String> clientsStorage = new ArrayList<String>();

    while (true) {
        //counter++;
        Socket serverClient = serverSocket.accept();    //Wait for client to connect      
        ServerClientThread sct = new ServerClientThread(serverClient);
        sct.start();          
    }
}

ServerClientThread是一个Thread类,我在ArrayList中添加一些值

public class ServerClientThread extends Thread{

Socket serverClient;
//int counter;

//int counter = 0;
   ServerClientThread(Socket inSocket) {
       serverClient = inSocket;
       //clientNo = counter;

}

   private volatile ArrayBlockingQueue<String> clientsStorage = new ArrayBlockingQueue<String>(10);
   //ArrayList<String> clientsStorage = new ArrayList<String>();
public void run(){  
      //counter++;
      try {
          ObjectInputStream inputValues = new ObjectInputStream(serverClient.getInputStream());
          Student12 received = (Student12) inputValues.readObject();

          if (received.getName().equals("Wrong!")) {

                //represent object to a text-output stream
                //System.out.println("Clients connected: " + clientNo);
                PrintWriter output = new PrintWriter(serverClient.getOutputStream(), true);
                output.println("Wrong typed value.Try again!");
                output.println("Name: Johny Domino Domino");
                output.println("Age: 27");
                output.println("Mark: 2");
                output.println("Email: johny_domino@gmx.com");
               // output.println("Clients connected: " + clientNo);
               inputValues.close();
                output.close();
                //serverClient.close();


            } 
            else {
                Counter12.clientsStorage.add(received.getName());
                int clientsNumber = Counter12.clientsStorage.size();

                System.out.println("Clients: " + clientsNumber);
                System.out.println("Client accepted: " + received.getName());
                PrintWriter output = new PrintWriter(serverClient.getOutputStream(), true);
                output.println("Student " + received.getName() + received.getEmail() + " has been received");
               output.println("Clients: " + clientsNumber);
                inputValues.close();
                output.close();
                //serverClient.close();

            }


    } catch (Exception e) {
        // TODO: handle exception
    }
  }  

}

Client类中,我应该从ArrayList中删除一些值,但我不能,因为程序显示ArrayList是空的

private static final long serialVersionUID = 7526472295622776147L;
//Creating fields, labels and area using JFrame class
JLabel labelName;
JLabel labelAge;
JLabel labelMark;
JLabel labelEmail;

JTextField txtFieldName;
JTextField txtFieldAge;
JTextField txtFieldMark;
JTextField txtFieldEmail;

JButton btnProcess;
JButton btnAddClient;
JButton btnLeave;
JButton btnExit;


JTextArea txtArea;



public Client12() {

     //Set parameters   
    this.setTitle("Simple Sample");
    this.setSize(420, 300);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    getContentPane().setLayout(null);

    labelName = new JLabel("Full Name: ");
    labelName.setBounds(10, 10, 120, 21);
    add(labelName);


    txtFieldName = new JTextField(); 
    txtFieldName.setBounds(105, 10, 120, 21);
    add(txtFieldName);

    labelAge = new JLabel("Age: ");
    labelAge.setBounds(10, 35, 120, 21);
    add(labelAge);

    txtFieldAge = new JTextField();
    txtFieldAge.setBounds(105, 35, 120, 21);
    add(txtFieldAge);

    labelMark = new JLabel("Mark: ");
    labelMark.setBounds(10, 60, 120, 21);
    add(labelMark);

    txtFieldMark = new JTextField();
    txtFieldMark.setBounds(105, 60, 120, 21);
    add(txtFieldMark);

    labelEmail = new JLabel("Email: ");
    labelEmail.setBounds(10, 85, 120, 21);
    add(labelEmail);

    txtFieldEmail = new JTextField();
    txtFieldEmail.setBounds(105, 85, 120, 21);
    add(txtFieldEmail);

    btnProcess = new JButton("Process");
    btnProcess.setBounds(250, 40, 120, 21);
    btnProcess.addActionListener(this);
    add(btnProcess);

    btnAddClient = new JButton("Add Client");
    btnAddClient.setBounds(250, 70, 120, 21);
    btnAddClient.addActionListener(this);
    add(btnAddClient);

    btnLeave = new JButton("Client Leave");
    btnLeave.setBounds(250, 100, 120, 21);
    btnLeave.addActionListener(this);
    add(btnLeave);

    btnExit = new JButton("Exit");
    btnExit.setBounds(250, 130, 120, 21);
    btnExit.addActionListener(this);
    add(btnExit);

    txtArea = new JTextArea();
    txtArea.setBounds(10, 120, 385, 150);
    txtArea.setLineWrap(true);
    txtArea.setWrapStyleWord(true);
    add(txtArea);


    this.setVisible(true);

}

public static void main(String[] args){
    new Client12(); 
}


@Override
public void actionPerformed(ActionEvent event) {
    if (event.getSource().equals(btnProcess)) {
        try {
            processInformation();
        } catch (UnknownHostException e1) {
            e1.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }
    else if (event.getSource().equals(btnAddClient)){
        new Client12();
    }

    else if (event.getSource().equals(btnLeave)){

        Counter12.clientsStorage.remove(0);
        System.out.println("Clients: " + Counter12.clientsStorage.size());
        setVisible(false);
        dispose(); //Destroy the JFrame object.
    }

    else if (event.getSource().equals(btnExit)){
        dispose();
        System.exit(0);
    }
}


//Method that process input information
public void processInformation() throws UnknownHostException, IOException {

    Socket s = new Socket("localhost", 5016);
    ObjectOutputStream p = new ObjectOutputStream(s.getOutputStream());

    String name = txtFieldName.getText();
    String markStr = txtFieldMark.getText();
    String ageStr = txtFieldAge.getText();   
    String email = txtFieldEmail.getText();

    //Checks if the user entered a properly formatted name, mark, age and email
    //RegEx name
    String patternName = ("^[A-Z]+[a-z]+\\s[A-Z]+[a-z]+\\s[A-Z]+[a-z]+$");
    Pattern patternCompileName = Pattern.compile(patternName);
    Matcher matcherName = patternCompileName.matcher(name);

    //RegEx mark
    String patternMark = ("^[0-6]$");
    Pattern patternCompileMark = Pattern.compile(patternMark);
    Matcher matcherMark = patternCompileMark.matcher(String.valueOf(markStr));

    //RegEx age
    String patternAge = ("\\d");
    Pattern patternCompileAge = Pattern.compile(patternAge);
    Matcher matcherAge = patternCompileAge.matcher(String.valueOf(ageStr));

    //RegEx email
    String patternEmail = ("[A-z0-9._%+-]+@[A-z0-9.-]+\\.[A-z]{2,5}");
    Pattern patternCompileEmail = Pattern.compile(patternEmail);
    Matcher matcherEmail = patternCompileEmail.matcher(email);

    int mark = 0;
    int age = 0;

    //Match the regular expressions
    if (matcherName.find() && matcherMark.find() && matcherAge.find() && matcherEmail.find()) {

         //counter++;
         mark = Integer.parseInt(markStr);
         age = Integer.parseInt(ageStr);
         //writes primitive data of the object to an OutputStream
         p.writeObject(new Student12(name, age, mark, email));
         p.flush();

        //Read the details from server
         BufferedReader response = new BufferedReader(new InputStreamReader(
                 s.getInputStream()));

         txtArea.setText("The server respond: " + response.readLine() + "\r\n");
         txtArea.append(response.readLine() + "\r\n");
         btnProcess.setEnabled(false);
         p.close();   
         response.close();
         s.close();
        // txtFieldName.setText("");
         //txtFieldAge.setText("");
        // txtFieldMark.setText("");
        // txtFieldEmail.setText("");
    }
    else {
        //If RegEx is false, we will set name = "Wrong!"
        p.writeObject(new Student12("Wrong!", age, mark, email));
        p.flush();

     BufferedReader response = new BufferedReader(new InputStreamReader(
                s.getInputStream()));

         txtArea.setText("The server respond: " + response.readLine() + "\r\n");
         txtArea.append("Example: " + "\r\n");
         txtArea.append(response.readLine() + "\r\n");
         txtArea.append(response.readLine() + "\r\n");
         txtArea.append(response.readLine() + "\r\n");
         txtArea.append(response.readLine());
         p.close();
         response.close();
         s.close();

        // txtFieldName.setText("");
         //txtFieldAge.setText("");
        // txtFieldMark.setText("");
         //txtFieldEmail.setText("");
    }  
}

我应该怎么做才能从 ServerClientThread 类添加值并从 Client 类中删除它们?

最佳答案

您似乎正在使用 ArrayList 作为队列:您在末尾添加,并从开头删除。所以最好使用Queue接口(interface)。多线程应用程序的典型队列实现是 ArrayBlockingQueue 。使用它代替 ArrayList

似乎您的一个线程正在尝试在另一个线程写入之前从数组列表中读取一个值。使用ArrayBlockingQueue,读取线程将等待另一个线程写入值。

关于java - 修改和访问线程类之外的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46789823/

相关文章:

java - 尝试访问匿名内部类中的 try-with-resource 资源时抛出异常

java - maven-compiler-plugin:3.8.1:compile 抛出 NullPointerException

python - Python 中意外的多线程 (scikit-learn)

ios - 抽象方法在Objective-C中实现多态

java - 无法加载没有绝对路径的图像

java - 实现linkedStack时出现NullPointerException

c# - 使用 Dispatcher 切换到 UI 线程的正确语法

java - GenericObjectPools borrowObject 方法线程安全吗?

java - Java 中的 "runtime class"是什么?

c++ - 创建用户所需的输入对象数 C++