我在使用java实现网络编程实例时,发现收发数据重复,特别是用udp网络协议的时候,观察发现服务器发送的数据和客户端接收的数据居然不同步,客户端收到的数据是上一次的重复!刚开始,我以为是丢包或者是DatagramSocket会缓存原数据,导致了重复读,但是服务器每次都重复发送两次,问题显然是在别的地方了。
我在服务器端使用了多线程来处理客户端的连接,使用newFixedThreadPool创建线程池,并调用execute执行线程,一个很简单的例子,怎么会有问题呢?原来是因为我在自己的线程类里面使用了start();其实,execute已经调用了start(),也就是线程对象重复执行了两次。客户端的send和receive都是阻塞的,所以就导致了收到的上一次服务端重复发送的数据。其实,还是我对Java的线程不熟悉导致的,居然不知道execute就已经执行线程了,没必要再调用start()。
低级的失误,我在查找问题的时候学到线程的另一些比较的重要的知识点,下面是我的一些个人见解和小结。
- Thread和Runnable
因为Java不支持多重继续,所以使用Runnable接口创建线程对象可以更加灵活。还有的文章说,Runnable能够实现资源共享:
MyThread mt=new MyThread();
new Thread(mt).start();
new Thread(mt).start();
其中
MyThread
implements
Runnable,这样就共享了mt线程对象。但是Thread其实也是可以的,这很容易理解因为Thread本身也是Runnable接口的子类,当线程执行的时候,都会去同一个给对象mt分配的地址上取值,也就是说操作的实际上是同一块堆栈地址。
- run()和start()
start()是启用一个新的用户线程执行对象的run函数。
- newFixedThreadPool和newCachedThreadPool