我有一个客户端,它将一个扩展Ellipse2D.Double
的TestEllipse发送到服务器。服务器将椭圆包装在ArrayList中,调用其updatePosition
方法,该方法将椭圆的x坐标加10,然后将列表发送回客户端。
当椭圆的x坐标等于或大于100时,椭圆应加到removeList
,它是......但它不是。在updatePosition
方法中,当我打印removeList
的大小时,输出结果为:
0 0 0 0 1 2 3 4 5
因此椭圆确实被添加到列表中(尽管多次,这是无关紧要的)。但是在main
方法中,它似乎根本没有添加椭圆,因为打印removeList
的大小会产生此输出:
0 0 0 0 0 0 0 0 0
我认为更改并未反映在各个主题之间,因此我尝试将removeList
标记为易变,但它没有帮助。
我还尝试创建一个返回removeList
的访问器方法,但这也不起作用。
如何将椭圆添加到removeList
,以便可以从main
方法进行访问?
在服务器端:
import java.io.*;
import java.net.*;
import java.util.*;
public class TestServer {
public static void main(String[] args) {
try {
List<TestClient.TestEllipse> list = new ArrayList<TestClient.TestEllipse>();
ServerSocket listener = new ServerSocket(31362);
Socket socket = listener.accept();
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
while (true) {
try {
TestClient.TestEllipse addEllipse = (TestClient.TestEllipse) ois.readObject();
if (addEllipse != null)
list.add(addEllipse);
TestClient.TestEllipse removeEllipse = (TestClient.TestEllipse) ois.readObject();
if (removeEllipse != null)
list.remove(removeEllipse);
for (TestClient.TestEllipse ellipse : list)
ellipse.updatePosition();
oos.writeObject(list);
oos.reset();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
在客户端:
import java.io.*;
import java.net.Socket;
import java.util.*;
public class TestClient implements Serializable {
static volatile List<TestEllipse> removeList = new ArrayList<TestEllipse>();
public static void main(String[] args) {
try {
List<TestEllipse> list = new ArrayList<TestEllipse>();
TestEllipse t = new TestClient().new TestEllipse(50, 250);
Socket socket = new Socket("localhost", 31362);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
while (true) {
try {
oos.writeObject(t);
t = null;
// System.out.print(removeList.size() + " ");
if (removeList.size() > 0)
oos.writeObject(removeList.remove(0));
else
oos.writeObject(null);
list = (List<TestEllipse>) ois.readObject();
Thread.sleep(500);
} catch (ClassNotFoundException | InterruptedException ex) {
ex.printStackTrace();
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
public class TestEllipse extends java.awt.geom.Ellipse2D.Double implements Serializable {
int x, y;
public TestEllipse(int x, int y) {
super(x,y,10,10);
this.x = x;
this.y = y;
}
public void updatePosition() {
if ((x += 10) >= 100)
removeList.add(this);
//System.out.print(removeList.size() + " ");
}
}
}
答案 0 :(得分:0)
您有两个独立的进程在运行。每个线程都在其自己的进程中。它们不共享TestClient中定义的removeList对象。在TestServer中调用ellipse.updatePosition()时,它会从列表中的椭圆上执行。该列表已在TestServer#main方法的范围中重新创建,并且与TestClient#main中定义的removeList没有任何关联。
可以修改TestEllipse本身以使其具有关于删除的状态:
public static class TestEllipse
extends java.awt.geom.Ellipse2D.Double
implements Serializable
{
int x, y;
boolean forRemove;
public void setForRemove(boolean forRemove)
{
this.forRemove = forRemove;
}
public boolean isForRemove()
{
return forRemove;
}
public TestEllipse(int x, int y)
{
super(x,y,10,10);
this.x = x;
this.y = y;
}
public void updatePosition()
{
if ((x += 10) >= 100)
{
setForRemove(true);
}
}
public String toString()
{
return String.format("{x:%d,y:%d,forRemove:%b}",x,y,isForRemove());
}
}
然后,当您有一个列表时,删除标记为要删除的省略号:
for (ListIterator<TestEllipse> li = list.listIterator() ; li.hasNext();)
{
TestEllipse elipse = (TestEllipse)li.next();
if (elipse.isForRemove())
{
li.remove();
}
}