为了账号安全,请及时绑定邮箱和手机立即绑定

当前线程本身在尝试调用另一个线程上的 wait() 时无限等待

当前线程本身在尝试调用另一个线程上的 wait() 时无限等待

侃侃无极 2021-12-22 16:03:24
我试图让另一个线程在下面的代码中等待,但我当前的线程本身正在无限等待。下面是两个 Java 类 Server.java,它们生成 ServerService.java 的可运行实例。当“ServerService.java”的这种运行实例调用Server.java.Server.java的入队方法时,应该让这样的被调用线程等待。但似乎我的 Server.java 线程本身无限等待服务器端.javaimport java.io.DataInputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Queue;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Server{    private ServerSocket server=null;    public static Map<Socket,String> clientsConnected=null;    public static Map<Socket,Runnable> clientsAndThreads=null;    public static ExecutorService executor=null;    public static List<Runnable> requestQueue=null;    public static Map<Runnable,Integer> threadAndRespectiveTime=null;    /*     * Contructor     */    Server(){        clientsConnected=new HashMap<Socket,String>();        clientsAndThreads=new HashMap<Socket,Runnable>();        threadAndRespectiveTime=new HashMap<>();        requestQueue=new ArrayList<>();    }下面是由 Server.java 作为线程产生的类
查看完整描述

1 回答

?
杨__羊羊

TA贡献1943条经验 获得超7个赞

My ServerService 线程实例在调用 Server.java 的 enqueue 方法后等待自身,而不是在产生的线程上调用 wait。然后Server.java 调用notify 来恢复ServerService 线程。


服务器端.java

import java.io.DataInputStream;

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.ArrayList;

import java.util.Date;

import java.util.HashMap;

import java.util.Iterator;

import java.util.LinkedList;

import java.util.List;

import java.util.Map;

import java.util.Queue;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.SynchronousQueue;


public class Server{

    private ServerSocket server=null;

    public static Map<Socket,String> clientsConnected=null;

    public static Map<Socket,Runnable> clientsAndThreads=null;

    public static ExecutorService executor=null;

    public static Queue<Thread> requestQueue=null;

    public static Map<Thread,Integer> threadAndRespectiveTime=null;

    /*

     * Contructor

     */

    Server(){

        clientsConnected=new HashMap<Socket,String>();

        clientsAndThreads=new HashMap<Socket,Runnable>();

        threadAndRespectiveTime=new HashMap<>();

        requestQueue=new LinkedList<>();

    }

    /*

     * Accepts connections from clients continually till the server is UP(max 10 clients)

     */

    public void acceptConnection(){

        try{

            executor=Executors.newFixedThreadPool(10);

            new Thread(new Runnable() {

                @Override

                public void run() {

                    Socket client=null;

                    while(server.isBound()){

                        try{

                            client=server.accept();

                            DataInputStream di= new DataInputStream(client.getInputStream());

                            String msg=di.readUTF();

                            clientsConnected.put(client, getMessage(msg));

                            ServerWindow.write(msg);

                            Runnable service= new ServerService(client,getMessage(msg));

                            executor.execute(service);

                        }catch(Exception e){

                            System.err.println("error occurred while accepting connections");

                        }

                    }

                }

            }).start();

            new Thread(new Runnable() {


                @Override

                public void run() {

                    try {

                        while(true){

                            Server.dequeue();

                        }

                    } catch (InterruptedException e) {

                        // TODO Auto-generated catch block

                        e.printStackTrace();

                    }

                }

            }).start();

        }catch(Exception e){

            System.err.println("Server:error while accepting connections"+e.getMessage());

        }

    }

    public static synchronized void enqueue(Thread t,Integer secondsToWait){

        try{

            System.out.println(requestQueue );

            threadAndRespectiveTime.put(t, secondsToWait);

            requestQueue.add(t);

        }catch(Exception e){

            e.printStackTrace();

        }

    }

    public static synchronized void dequeue() throws InterruptedException{

        while(!requestQueue.isEmpty()){

            Thread currentThread=requestQueue.remove();

            Integer timeToWait=threadAndRespectiveTime.get(currentThread);

            System.out.println("time to wait is:"+timeToWait);

            Thread.currentThread().sleep(timeToWait * 1000);

            synchronized (currentThread) {

                currentThread.notify();

            }

        }

    }

    /*

     * This method takes out actual message from http format

     */

    public String getMessage(String str){

        return str.substring(str.indexOf("message:")+8, str.length());

    }

    /*

     * Starts the server listening to port 4000

     */

    public void start_server(){

        try{

            if(server==null || !server.isBound()){

                server = new ServerSocket(4000);

            }

            acceptConnection();

        }catch(Exception e){

            System.err.println("Server:error occurred while server start"+e.getMessage());

        }

    }

    /*

     * Closes client sockets of every connected client, shuts down the thread executor that serves clients

     */

    public void stop_server() throws IOException{

        Iterator it=clientsConnected.entrySet().iterator();

        while(it.hasNext()){

            Map.Entry e= (Map.Entry)it.next();

            Socket toBeClosed=(Socket)e.getKey();

            toBeClosed.close();

        }

        executor.shutdownNow();

        server.close();

    }

}

服务器服务.java


==================


    import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.IOException;

import java.net.Socket;

import java.util.Date;

/*

 * This class serves the client

 */

public class ServerService extends Server implements Runnable{

    private Socket client=null;

    private String clientBeingServed=null;

    private DataOutputStream dout=null;

    private DataInputStream din=null;

    /*

     * This is construcor that takes client sockte that already has been connected to server and client name.

     * It initializes and input and output streams for serving the respective client

     */

    public ServerService(Socket client,String name) throws IOException {

        this.client=client;

        this.clientBeingServed=name;

        dout=new DataOutputStream(client.getOutputStream());

        din=new DataInputStream(client.getInputStream());

    }

    /*

     * takes out actual message sent by client from its http format

     */

    public String getMessage(String str){

        //System.out.println("returning\n"+str.substring(str.indexOf("message:")+8, str.length()));

        return str.substring(str.indexOf("message:")+8, str.length());

    }

    /*

     * This method converts a message string into HTTP formatted string

     */

    public String getHttpMessage(String msg){

        String str="POST Http/1.1 \n" + "Host: www.uta.com \n" + "User-Agent: Mozilla/5.0 \n"

                + "Content=type: application/x-www-form-urlencoded \n" + "Content-Length: " + msg.length() + " \n"

                + "Date:" + new Date() + " \n" + "message:" + msg;

        return str;

    }

    /*

     * This method execute when thread for this class is executed from Server.java file after connection is accepted

     */

    @Override

    public void run() {

        int waitTime=0;

        try{

            while(client.isConnected()){

                    String msg=din.readUTF();

                    ServerWindow.write(msg);

                    waitTime=Integer.parseInt(getMessage(msg));

                    System.out.println("Equeing:"+clientBeingServed);

                    Server.enqueue(Thread.currentThread(), waitTime);

                    System.out.println("before going to sleep");

                    synchronized (Thread.currentThread()) {

                        Thread.currentThread().wait();

                    }

                    System.out.println("after sleeping");

                    ServerWindow.write("Served client:"+clientBeingServed);

                    dout.writeUTF(getHttpMessage("Server waited "+waitTime+" seconds for "+clientBeingServed));

                    dout.flush();

            }

            client.close();

        }catch(Exception e){

            System.err.println("ServerService:error serving client"+clientBeingServed+e.getMessage());

        }

    }

}



查看完整回答
反对 回复 2021-12-22
  • 1 回答
  • 0 关注
  • 150 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信