为何我的static 定义的Vector变量在不同类之间不能共同使用,解惑后,狂送分

时间:2022-11-13 20:05:49
代码不贴了,太长了,我做的一个模拟QQ聊天的程序
在服务器里定义了一个static Vector<ServerThread> clientList;用来装客户端的代理线程

在ServerThread里,给clientList添加了元素后,经过测试,clientList确实有了元素不是Null了。

可是在客户端的代理线程里,clientList始终是null;

这种情况应是什么原因,

程序的先后吗?可是我是在修改了clientList后,才通知的客户端

12 个解决方案

#1


static Vector<ServerThread> clientList; 
你定义的时候并没有赋值吧,看下什么时候赋值的;另外客户端的代理线程需要每次都直接去取 clientList,而不是取了一次放到成员里面,因为如果取的那次刚好返回 null 的话,那就一直都是 null 了。

#2


引用 1 楼 YidingHe 的回复:
static Vector<ServerThread> clientList; 
你定义的时候并没有赋值吧,看下什么时候赋值的;另外客户端的代理线程需要每次都直接去取 clientList,而不是取了一次放到成员里面,因为如果取的那次刚好返回 null 的话,那就一直都是 null 了。


如何直接引用 ?我都在通知客户端clientList修改了后,然后直接用Server.clientList去访问的,这样不对吗,我没有放到我的类中,直接用类名.clientList去使用

#3


你是不是,服务端启动一次,客户端启动一次。他们分别在两个进程里面?

#4


引用 3 楼 Q80470101 的回复:
你是不是,服务端启动一次,客户端启动一次。他们分别在两个进程里面?

服务端启动一次,初始化clientList。客户端里,在一个方法里会调用clientList,这个方法是在服务器代理程序修改clientList后,通知客户端调用这个方法来使用clientList。

#5


引用 4 楼 qq_34333347 的回复:
Quote: 引用 3 楼 Q80470101 的回复:

你是不是,服务端启动一次,客户端启动一次。他们分别在两个进程里面?

服务端启动一次,初始化clientList。客户端里,在一个方法里会调用clientList,这个方法是在服务器代理程序修改clientList后,通知客户端调用这个方法来使用clientList。

先明确一下,是一个进程还是两个,如果是两个的话,两个进程间的list是独立的,是不会共享数据的。

#6


引用 5 楼 Q80470101 的回复:
Quote: 引用 4 楼 qq_34333347 的回复:

Quote: 引用 3 楼 Q80470101 的回复:

你是不是,服务端启动一次,客户端启动一次。他们分别在两个进程里面?

服务端启动一次,初始化clientList。客户端里,在一个方法里会调用clientList,这个方法是在服务器代理程序修改clientList后,通知客户端调用这个方法来使用clientList。

先明确一下,是一个进程还是两个,如果是两个的话,两个进程间的list是独立的,是不会共享数据的。


三个三程,clientList是在主线程中定义的public static 变量。其中一个线修改后,通知第二个线程调用,并且我让第二个线程sleep五秒,防止同步问题。结果还是不行。我又在 主线程里加了两个static 定义的变量,然后让主线程和第二个线程修改他,结果发现,第三个线程只能调用到这几个变量声明时的值,修改后的值调用不到

#7


下面这些是我从百度上看到的,他解释的好像对,可是没有说明解决办法啊,哪个大神知道
自己写的小程序,分为Server和client,都执行了定时任务。当Server和client同时更改static变量tempList时,理论上会出现数据混乱的情况,但是从没有出现。所以我将server端的时间向后调了一分钟。但是client的程序打印的结果还是没有因为server改变tempList而改变。请教一下,谁能抽几分钟时间,帮我看看,谢谢

public class Server {
public static List<String> tempList = new ArrayList<String>(
public static void main(String[] args) throws Exception{
     String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
     dateStr+="224500";
     Timer timer = new Timer();
     timer.scheduleAtFixedRate(new TimerTask(){
     @Override
     public void run() {
         System.out.println(System.currentTimeMillis());
         tempList.clear();
         tempList.add("bbb");
     }
     }, new SimpleDateFormat("yyyyMMddHHmmss").parse(dateStr),180000);
}

public static List<String> getTempList(){
synchronized (Server.class) {
     if(tempList.size()==0){
     tempList.add("aaa");
     }
  }
return tempList;
}
}

public class Client implements Runnable{
public static void main(String[] args) throws Exception{
String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
dateStr+="224400";
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask(){
@Override
public void run() {
System.out.println(System.currentTimeMillis());
System.out.println("..."+Server.tempList);
Client client = new Client();
for(int i=0;i<10;i++){
Thread t = new Thread(client);
t.start();
}
}

}, new SimpleDateFormat("yyyyMMddHHmmss").parse(dateStr),180000);
}
@Override
public void run() {
System.out.println("tempList: "+Server.getTempList());
}
}
2014-12-01 23:18 #2016年高质量新标准全面升级!# 提问者采纳
Server和Client分别是2个main方法?那你不是相当于启动了2个java虚拟机来分别运行Server和Client的程序么。。。这样的话当然相互之间不会有影响啦。
提问者评价
短短几句话,就解决了我心中的疑问,看来我还是太水了啊,谢谢了。

#8


引用 7 楼 qq_34333347 的回复:
下面这些是我从百度上看到的,他解释的好像对,可是没有说明解决办法啊,哪个大神知道
自己写的小程序,分为Server和client,都执行了定时任务。当Server和client同时更改static变量tempList时,理论上会出现数据混乱的情况,但是从没有出现。所以我将server端的时间向后调了一分钟。但是client的程序打印的结果还是没有因为server改变tempList而改变。请教一下,谁能抽几分钟时间,帮我看看,谢谢

public class Server {
public static List<String> tempList = new ArrayList<String>(
public static void main(String[] args) throws Exception{
     String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
     dateStr+="224500";
     Timer timer = new Timer();
     timer.scheduleAtFixedRate(new TimerTask(){
     @Override
     public void run() {
         System.out.println(System.currentTimeMillis());
         tempList.clear();
         tempList.add("bbb");
     }
     }, new SimpleDateFormat("yyyyMMddHHmmss").parse(dateStr),180000);
}

public static List<String> getTempList(){
synchronized (Server.class) {
     if(tempList.size()==0){
     tempList.add("aaa");
     }
  }
return tempList;
}
}

public class Client implements Runnable{
public static void main(String[] args) throws Exception{
String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
dateStr+="224400";
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask(){
@Override
public void run() {
System.out.println(System.currentTimeMillis());
System.out.println("..."+Server.tempList);
Client client = new Client();
for(int i=0;i<10;i++){
Thread t = new Thread(client);
t.start();
}
}

}, new SimpleDateFormat("yyyyMMddHHmmss").parse(dateStr),180000);
}
@Override
public void run() {
System.out.println("tempList: "+Server.getTempList());
}
}
2014-12-01 23:18 #2016年高质量新标准全面升级!# 提问者采纳
Server和Client分别是2个main方法?那你不是相当于启动了2个java虚拟机来分别运行Server和Client的程序么。。。这样的话当然相互之间不会有影响啦。
提问者评价
短短几句话,就解决了我心中的疑问,看来我还是太水了啊,谢谢了。

说的就是这个问题啊。两个main方法就相当于两个进程,数据间是不会共享的。

#9


把它改成一个进程(一个main方法),然后里面分别开启server 和client线程,线程间数据是可以共享的。

#10


引用 9 楼 Q80470101 的回复:
把它改成一个进程(一个main方法),然后里面分别开启server 和client线程,线程间数据是可以共享的。

那以后做软件,服务器和客户端可是不能放到一个main方法里啊,服务端由一方开启,客户端需要别一方去开启,不能放一个main里,应该还有别的方法吧

#11


我突然明白了,突然明白怎么回事了,太好了,纠结了我好几天啊!!!!服务器端修改了变量,客户端想读到,一定是通过Socket传过去才可以的。我刚开始学,在一台电脑上运行,相当然的以为,客户端会自动去读服务器里修改后的变量。这其实是两个不同的进程之间的通信啊!!! 为何我的static 定义的Vector变量在不同类之间不能共同使用,解惑后,狂送分

#12


引用 11 楼 qq_34333347 的回复:
我突然明白了,突然明白怎么回事了,太好了,纠结了我好几天啊!!!!服务器端修改了变量,客户端想读到,一定是通过Socket传过去才可以的。我刚开始学,在一台电脑上运行,相当然的以为,客户端会自动去读服务器里修改后的变量。这其实是两个不同的进程之间的通信啊!!! 为何我的static 定义的Vector变量在不同类之间不能共同使用,解惑后,狂送分

#1


static Vector<ServerThread> clientList; 
你定义的时候并没有赋值吧,看下什么时候赋值的;另外客户端的代理线程需要每次都直接去取 clientList,而不是取了一次放到成员里面,因为如果取的那次刚好返回 null 的话,那就一直都是 null 了。

#2


引用 1 楼 YidingHe 的回复:
static Vector<ServerThread> clientList; 
你定义的时候并没有赋值吧,看下什么时候赋值的;另外客户端的代理线程需要每次都直接去取 clientList,而不是取了一次放到成员里面,因为如果取的那次刚好返回 null 的话,那就一直都是 null 了。


如何直接引用 ?我都在通知客户端clientList修改了后,然后直接用Server.clientList去访问的,这样不对吗,我没有放到我的类中,直接用类名.clientList去使用

#3


你是不是,服务端启动一次,客户端启动一次。他们分别在两个进程里面?

#4


引用 3 楼 Q80470101 的回复:
你是不是,服务端启动一次,客户端启动一次。他们分别在两个进程里面?

服务端启动一次,初始化clientList。客户端里,在一个方法里会调用clientList,这个方法是在服务器代理程序修改clientList后,通知客户端调用这个方法来使用clientList。

#5


引用 4 楼 qq_34333347 的回复:
Quote: 引用 3 楼 Q80470101 的回复:

你是不是,服务端启动一次,客户端启动一次。他们分别在两个进程里面?

服务端启动一次,初始化clientList。客户端里,在一个方法里会调用clientList,这个方法是在服务器代理程序修改clientList后,通知客户端调用这个方法来使用clientList。

先明确一下,是一个进程还是两个,如果是两个的话,两个进程间的list是独立的,是不会共享数据的。

#6


引用 5 楼 Q80470101 的回复:
Quote: 引用 4 楼 qq_34333347 的回复:

Quote: 引用 3 楼 Q80470101 的回复:

你是不是,服务端启动一次,客户端启动一次。他们分别在两个进程里面?

服务端启动一次,初始化clientList。客户端里,在一个方法里会调用clientList,这个方法是在服务器代理程序修改clientList后,通知客户端调用这个方法来使用clientList。

先明确一下,是一个进程还是两个,如果是两个的话,两个进程间的list是独立的,是不会共享数据的。


三个三程,clientList是在主线程中定义的public static 变量。其中一个线修改后,通知第二个线程调用,并且我让第二个线程sleep五秒,防止同步问题。结果还是不行。我又在 主线程里加了两个static 定义的变量,然后让主线程和第二个线程修改他,结果发现,第三个线程只能调用到这几个变量声明时的值,修改后的值调用不到

#7


下面这些是我从百度上看到的,他解释的好像对,可是没有说明解决办法啊,哪个大神知道
自己写的小程序,分为Server和client,都执行了定时任务。当Server和client同时更改static变量tempList时,理论上会出现数据混乱的情况,但是从没有出现。所以我将server端的时间向后调了一分钟。但是client的程序打印的结果还是没有因为server改变tempList而改变。请教一下,谁能抽几分钟时间,帮我看看,谢谢

public class Server {
public static List<String> tempList = new ArrayList<String>(
public static void main(String[] args) throws Exception{
     String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
     dateStr+="224500";
     Timer timer = new Timer();
     timer.scheduleAtFixedRate(new TimerTask(){
     @Override
     public void run() {
         System.out.println(System.currentTimeMillis());
         tempList.clear();
         tempList.add("bbb");
     }
     }, new SimpleDateFormat("yyyyMMddHHmmss").parse(dateStr),180000);
}

public static List<String> getTempList(){
synchronized (Server.class) {
     if(tempList.size()==0){
     tempList.add("aaa");
     }
  }
return tempList;
}
}

public class Client implements Runnable{
public static void main(String[] args) throws Exception{
String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
dateStr+="224400";
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask(){
@Override
public void run() {
System.out.println(System.currentTimeMillis());
System.out.println("..."+Server.tempList);
Client client = new Client();
for(int i=0;i<10;i++){
Thread t = new Thread(client);
t.start();
}
}

}, new SimpleDateFormat("yyyyMMddHHmmss").parse(dateStr),180000);
}
@Override
public void run() {
System.out.println("tempList: "+Server.getTempList());
}
}
2014-12-01 23:18 #2016年高质量新标准全面升级!# 提问者采纳
Server和Client分别是2个main方法?那你不是相当于启动了2个java虚拟机来分别运行Server和Client的程序么。。。这样的话当然相互之间不会有影响啦。
提问者评价
短短几句话,就解决了我心中的疑问,看来我还是太水了啊,谢谢了。

#8


引用 7 楼 qq_34333347 的回复:
下面这些是我从百度上看到的,他解释的好像对,可是没有说明解决办法啊,哪个大神知道
自己写的小程序,分为Server和client,都执行了定时任务。当Server和client同时更改static变量tempList时,理论上会出现数据混乱的情况,但是从没有出现。所以我将server端的时间向后调了一分钟。但是client的程序打印的结果还是没有因为server改变tempList而改变。请教一下,谁能抽几分钟时间,帮我看看,谢谢

public class Server {
public static List<String> tempList = new ArrayList<String>(
public static void main(String[] args) throws Exception{
     String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
     dateStr+="224500";
     Timer timer = new Timer();
     timer.scheduleAtFixedRate(new TimerTask(){
     @Override
     public void run() {
         System.out.println(System.currentTimeMillis());
         tempList.clear();
         tempList.add("bbb");
     }
     }, new SimpleDateFormat("yyyyMMddHHmmss").parse(dateStr),180000);
}

public static List<String> getTempList(){
synchronized (Server.class) {
     if(tempList.size()==0){
     tempList.add("aaa");
     }
  }
return tempList;
}
}

public class Client implements Runnable{
public static void main(String[] args) throws Exception{
String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
dateStr+="224400";
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask(){
@Override
public void run() {
System.out.println(System.currentTimeMillis());
System.out.println("..."+Server.tempList);
Client client = new Client();
for(int i=0;i<10;i++){
Thread t = new Thread(client);
t.start();
}
}

}, new SimpleDateFormat("yyyyMMddHHmmss").parse(dateStr),180000);
}
@Override
public void run() {
System.out.println("tempList: "+Server.getTempList());
}
}
2014-12-01 23:18 #2016年高质量新标准全面升级!# 提问者采纳
Server和Client分别是2个main方法?那你不是相当于启动了2个java虚拟机来分别运行Server和Client的程序么。。。这样的话当然相互之间不会有影响啦。
提问者评价
短短几句话,就解决了我心中的疑问,看来我还是太水了啊,谢谢了。

说的就是这个问题啊。两个main方法就相当于两个进程,数据间是不会共享的。

#9


把它改成一个进程(一个main方法),然后里面分别开启server 和client线程,线程间数据是可以共享的。

#10


引用 9 楼 Q80470101 的回复:
把它改成一个进程(一个main方法),然后里面分别开启server 和client线程,线程间数据是可以共享的。

那以后做软件,服务器和客户端可是不能放到一个main方法里啊,服务端由一方开启,客户端需要别一方去开启,不能放一个main里,应该还有别的方法吧

#11


我突然明白了,突然明白怎么回事了,太好了,纠结了我好几天啊!!!!服务器端修改了变量,客户端想读到,一定是通过Socket传过去才可以的。我刚开始学,在一台电脑上运行,相当然的以为,客户端会自动去读服务器里修改后的变量。这其实是两个不同的进程之间的通信啊!!! 为何我的static 定义的Vector变量在不同类之间不能共同使用,解惑后,狂送分

#12


引用 11 楼 qq_34333347 的回复:
我突然明白了,突然明白怎么回事了,太好了,纠结了我好几天啊!!!!服务器端修改了变量,客户端想读到,一定是通过Socket传过去才可以的。我刚开始学,在一台电脑上运行,相当然的以为,客户端会自动去读服务器里修改后的变量。这其实是两个不同的进程之间的通信啊!!! 为何我的static 定义的Vector变量在不同类之间不能共同使用,解惑后,狂送分