java tcp socket 线程同步

问题描述

代码功能:客户端输入三个整数,服务器端返回客户端这三个整数的和我的思路服务器端起两个线程,一个监听,一个向客户端写出数据的线程,当收到数据后,用notify()唤醒写出线程,但我下面的代码输出端一直wait在那里,notify()都没用,不能实现同步啊publicclassServer{/**Server*/publicstaticfinalintPORT=6666;privateServerSocketserver=null;privateSocketclient=null;privateinta,b,c;privatebooleanflag=false;publicServer(){}publicvoidbegin(){try{server=newServerSocket(PORT);System.out.println("Server:serverstarting...");client=server.accept();System.out.println("Server:aclientconnect!");newThread(newReadThread()).start();newThread(newWriteThread()).start();}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}classReadThreadimplementsRunnable{@Overridepublicvoidrun(){synchronized(this){try{DataInputStreamdis=newDataInputStream(client.getInputStream());while(true){a=dis.readInt();b=dis.readInt();c=dis.readInt();System.out.println("Server:"+a+","+b+","+c);flag=true;notify();}}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}}classWriteThreadimplementsRunnable{@Overridepublicvoidrun(){synchronized(this){try{DataOutputStreamdos=newDataOutputStream(client.getOutputStream());while(true){if(!flag){try{wait();System.out.println("Server:wakeup");}catch(InterruptedExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}dos.writeInt(a+b+c);dos.flush();//dos.close();flag=false;}}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}}publicstaticvoidmain(String[]args){newServer().begin();}}

客户端publicclassClient{/**Client*/privateSocketclient=null;publicvoidbegin(){try{client=newSocket("127.0.0.1",Server.PORT);System.out.println("Client:connecttoserver!");newThread(newReadThread()).start();newThread(newWriteThread()).start();}catch(UnknownHostExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}classReadThreadimplementsRunnable{@Overridepublicvoidrun(){try{DataInputStreamdis=newDataInputStream(client.getInputStream());while(true){intn=dis.readInt();System.out.println("Client:"+n);}}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}classWriteThreadimplementsRunnable{@Overridepublicvoidrun(){try{DataOutputStreamdos=newDataOutputStream(client.getOutputStream());Scannersc=newScanner(System.in);while(true){System.out.print("输入a:");inta=sc.nextInt();System.out.print("输入b:");intb=sc.nextInt();System.out.print("输入c:");intc=sc.nextInt();dos.writeInt(a);dos.writeInt(b);dos.writeInt(c);}}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}publicstaticvoidmain(String[]args){newClient().begin();}}

求大侠指教

解决方案

解决方案二:
你的服务端ReadThread和WriteThread的run方法整体用this同步,当其中一个获得锁的时候,另外一个线程永远获得不了锁。即使你调用notify.因为同步块代码没有执行完,所以锁没有释放。可以改成同步只对wait和write起作用
解决方案三:
也就是同步去掉,改为在42行和64行加上同步
解决方案四:
改了之后的服务端代码,才看见你的服务端同步代码锁是this.。。。。你需要好好考虑下this啥意思publicclassTestSocketClient{/**Client*/privateSocketclient=null;publicvoidbegin(){try{client=newSocket("127.0.0.1",6666);System.out.println("Client:connecttoserver!");newThread(newReadThread()).start();newThread(newWriteThread()).start();}catch(UnknownHostExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}classReadThreadimplementsRunnable{@Overridepublicvoidrun(){try{DataInputStreamdis=newDataInputStream(client.getInputStream());while(true){intn=dis.readInt();System.out.println("Client:"+n);}}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}classWriteThreadimplementsRunnable{@Overridepublicvoidrun(){try{DataOutputStreamdos=newDataOutputStream(client.getOutputStream());Scannersc=newScanner(System.in);while(true){System.out.print("输入a:");inta=sc.nextInt();System.out.print("输入b:");intb=sc.nextInt();System.out.print("输入c:");intc=sc.nextInt();dos.writeInt(a);dos.writeInt(b);dos.writeInt(c);}}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}publicstaticvoidmain(String[]args){newTestSocketClient().begin();}}

解决方案五:
。。。需要同步的是两个是内部类,所以要实现两个不同类对象的同步,怎么搞
解决方案六:
引用4楼u013351347的回复:

。。。需要同步的是两个是内部类,所以要实现两个不同类对象的同步,怎么搞

内部类可以访问外部类的变量,这有什么问题,并且我代码都给你写出来了
解决方案七:
。。。。你给的是客户端,请给我一下服务器端
解决方案八:
按照楼主的思路可以很简单的完成,你的wait与notify没有用的。read和write是两个独立的线程,没有任何公共资源,wait后是不能被唤醒。楼主可以去看看生产者消费者的例子。了解一下wait与notify的用法。wait与notify方法是object类的,根据楼主的意思,我用了两个线程来完成,楼主可以参考下。/****/packagecom.ball.thread;importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.IOException;importjava.net.Socket;importjava.net.UnknownHostException;importjava.util.Scanner;/***@authoradmin**/publicclassWriteThreadimplementsRunnable{Socketsocket;booleanflag=true;publicvoidrun(){try{socket=newSocket("127.0.0.1",8421);}catch(UnknownHostExceptione1){//TODOAuto-generatedcatchblocke1.printStackTrace();}catch(IOExceptione1){//TODOAuto-generatedcatchblocke1.printStackTrace();}try{DataOutputStreamdos=newDataOutputStream(socket.getOutputStream());DataInputStreamdis=newDataInputStream(socket.getInputStream());Scannersc=newScanner(System.in);while(flag){System.out.print("输入a:");inta=sc.nextInt();System.out.print("输入b:");intb=sc.nextInt();System.out.print("输入c:");intc=sc.nextInt();dos.writeInt(a);dos.writeInt(b);dos.writeInt(c);inti=dis.readInt();System.out.println(i);}}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}

/****/packagecom.ball.thread;importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.IOException;importjava.net.ServerSocket;importjava.net.Socket;/***@authoradmin**/publicclassReadThreadimplementsRunnable{publicvoidrun(){ServerSocketss;Socketsocket=null;try{ss=newServerSocket(8421);socket=ss.accept();}catch(IOExceptione1){//TODOAuto-generatedcatchblocke1.printStackTrace();}try{DataInputStreamdis=newDataInputStream(socket.getInputStream());DataOutputStreamdos=newDataOutputStream(socket.getOutputStream());while(true){inta=dis.readInt();intb=dis.readInt();intc=dis.readInt();System.out.println("Server:"+a+","+b+","+c);intsum=a+b+c;dos.writeInt(sum);}}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}

/****/packagecom.ball.thread;importjava.io.IOException;importjava.net.ServerSocket;importjava.net.Socket;/***@authoradmin**/publicclassTest{publicstaticvoidmain(String[]args){Threadthread1=newThread(newWriteThread());thread1.start();Threadthread2=newThread(newReadThread());thread2.start();}}

解决方案九:
按照楼主的思路,又重新写了一下代码。服务端:公共类:/****/packagecom.ball.thread;/***@authoradmin**/publicclassCommon{privateinta;privateintb;privateintc;/***@returnthea*/publicintgetA(){returna;}/***@paramatheatoset*/publicvoidsetA(inta){this.a=a;}/***@returntheb*/publicintgetB(){returnb;}/***@parambthebtoset*/publicvoidsetB(intb){this.b=b;}/***@returnthec*/publicintgetC(){returnc;}/***@paramcthectoset*/publicvoidsetC(intc){this.c=c;}privatebooleanflag=false;publicsynchronizedvoidsetNum(inta,intb,intc){if(flag){try{super.wait();}catch(InterruptedExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}this.setA(a);this.setB(b);this.setC(c);flag=true;super.notify();}publicsynchronizedintadd(){intcount=0;if(!flag){try{super.wait();}catch(InterruptedExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}count=this.getA()+this.getB()+this.getC();flag=false;super.notify();returncount;}}

读线程:/****/packagecom.ball.thread;importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.IOException;importjava.net.ServerSocket;importjava.net.Socket;/***@authoradmin**/publicclassReadThreadimplementsRunnable{privateCommoncommon;Socketsocket;publicReadThread(Socketsocket,Commoncommon){this.common=common;this.socket=socket;}publicvoidrun(){try{DataInputStreamdis=newDataInputStream(socket.getInputStream());DataOutputStreamdos=newDataOutputStream(socket.getOutputStream());while(true){inta=dis.readInt();intb=dis.readInt();intc=dis.readInt();System.out.println("Server:"+a+","+b+","+c);common.setNum(a,b,c);}}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}

加法:/****/packagecom.ball.thread;importjava.io.DataOutputStream;importjava.io.IOException;importjava.net.Socket;/***@authoradmin**/publicclassAddThreadimplementsRunnable{privateCommoncommon;privateSocketsocket;publicAddThread(Socketsocket,Commoncommon){this.common=common;this.socket=socket;}publicvoidrun(){while(true){intsum=common.add();try{DataOutputStreamdos=newDataOutputStream(socket.getOutputStream());dos.writeInt(sum);}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}}

客户端:/****/packagecom.ball.thread;importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.IOException;importjava.net.Socket;importjava.net.UnknownHostException;importjava.util.Scanner;/***@authoradmin**/publicclassWriteThreadimplementsRunnable{publicstaticvoidmain(String[]args){Threadthread1=newThread(newWriteThread());thread1.start();}Socketsocket;booleanflag=true;publicvoidrun(){try{socket=newSocket("127.0.0.1",8421);}catch(UnknownHostExceptione1){//TODOAuto-generatedcatchblocke1.printStackTrace();}catch(IOExceptione1){//TODOAuto-generatedcatchblocke1.printStackTrace();}try{DataOutputStreamdos=newDataOutputStream(socket.getOutputStream());DataInputStreamdis=newDataInputStream(socket.getInputStream());Scannersc=newScanner(System.in);while(flag){System.out.print("输入a:");inta=sc.nextInt();System.out.print("输入b:");intb=sc.nextInt();System.out.print("输入c:");intc=sc.nextInt();dos.writeInt(a);dos.writeInt(b);dos.writeInt(c);inti=dis.readInt();System.out.println(i);}}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}

测试:/****/packagecom.ball.thread;importjava.io.IOException;importjava.net.ServerSocket;importjava.net.Socket;/***@authoradmin**/publicclassTest{publicstaticvoidmain(String[]args){Commoncommon=newCommon();ServerSocketss;Socketsocket=null;try{ss=newServerSocket(8421);socket=ss.accept();}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}Threadthread1=newThread(newReadThread(socket,common));thread1.start();Threadthread2=newThread(newAddThread(socket,common));thread2.start();}}

解决方案十:
太感谢了。那天我问我老师,他说服务器端没必要起2个线程来监控读和写,最好写在一起
解决方案十一:
恩,这种问题可以不必写wait与notify,按我第一个就能完成。楼主如果有兴趣可以看看生产者与消费者的例子,那里用到可wait与notify
解决方案十二:
加一个异步吧synchronized(A.thread){A.thread.notify();}

时间: 2024-12-03 11:31:37

java tcp socket 线程同步的相关文章

关于java 中的线程同步问题,求大神解释。

问题描述 关于java 中的线程同步问题,求大神解释. 对于一个已经继承了Runnable 接口的类来说,假设创建了一个它的实例为 account, 那么: for(int i=0;i<500;i++) { new Thread(account).start(); } 不会造成500个线程同步访问同一资源而引发冲突? 为什么: private ExecutorService executor = Executors.newCachedThreadPool(); //在线程池中为每个等待的任务创建

Java中的线程同步与ThreadLocal无锁化线程封闭实现_java

Synchronized关键字 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块. 然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(

JAVA生产者消费者(线程同步)代码学习示例_java

一.问题描述 生产者消费者问题是一个典型的线程同步问题.生产者生产商品放到容器中,容器有一定的容量(只能顺序放,先放后拿),消费者消费商品,当容器满了后,生产者等待,当容器为空时,消费者等待.当生产者将商品放入容器后,通知消费者:当消费者拿走商品后,通知生产者. 二.解决方案 对容器资源加锁,当取得锁后,才能对互斥资源进行操作. 复制代码 代码如下: public class ProducerConsumerTest {     public static void main(String []

Java服务器端Socket线程池

import java.util.Vector; import java.net.*; import java.io.*; public class ThreadPool { public static final int MAX_THREADS = 100; public static final int MAX_SPARE_THREADS = 50; public static final int MIN_SPARE_THREADS = 10; public static final int

详解Java编程中线程同步以及定时启动线程的方法_java

使用wait()与notify()实现线程间协作 1. wait()与notify()/notifyAll()调用sleep()和yield()的时候锁并没有被释放,而调用wait()将释放锁.这样另一个任务(线程)可以获得当前对象的锁,从而进入它的synchronized方法中.可以通过notify()/notifyAll(),或者时间到期,从wait()中恢复执行. 只能在同步控制方法或同步块中调用wait().notify()和notifyAll().如果在非同步的方法里调用这些方法,在运

java tcp socket实现

tcpServer: public class MyTcpServer implements Runnable { private ServerSocket serverSocket; private ExecutorService pool = Executors.newCachedThreadPool(); public MyTcpServer(int port) throws IOException { serverSocket = new ServerSocket(port); } @O

Java线程同步实例分析_java

本文实例讲述了Java线程同步的用法.分享给大家供大家参考.具体分析如下: 多线程的使用为我们的程序提供了众多的方便,同时它也给我们带来了以往没有考虑过的麻烦.当我们使用多线程处理共享资源时意外将会发生:比如我们一起外出就餐,每个人都是一个线程,餐桌上的食物则是共享资源,当我看到红烧鸡腿上桌后立即拿起筷子直奔目标,眼看着就得手的时候,突然---鸡腿消失了,一个距离盘子更近的线程正在得意地啃着. 为了避免上述问题的发生,Java为我们提供了"synchronized(同步化)修饰符"来避

java中的线程

编写具有多线程能力的程序经常会用到的方法有: run(),start(),wait(),notify(),notifyAll(),sleep(),yield(),join() 还有一个重要的关键字:synchronized 本文将对以上内容进行讲解. 一:run()和start() 示例1: public class threadtest extends thread{public void run(){for(int i=0;i<10;i++){system.out.print(" &q

synchronized-问java中关于线程同步的问题

问题描述 问java中关于线程同步的问题 public class TT implements Runnable { int b = 100; public synchronized void m1() throws Exception { b = 1000; Thread.sleep(2500); System.out.println("b = " + b); } public synchronized void m2() throws Exception { Thread.slee