我是 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/