Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
同步线程通信是Java的,只使用原语结构_Java_Multithreading_Concurrency - Fatal编程技术网

同步线程通信是Java的,只使用原语结构

同步线程通信是Java的,只使用原语结构,java,multithreading,concurrency,Java,Multithreading,Concurrency,我正在努力实现服务器和客户端线程子类(模拟)之间的完美通信。我读了很多文章,但我想我还没有掌握如何同步线程的基本概念 问题: 我的服务器正在接收来自所有三个客户端的请求,关闭后,客户端将打印从服务器收到的回复。但服务器应该首先响应客户机,然后从其他线程获得另一个请求。 我们将非常感谢你的帮助。谢谢 以下是所涉及的课程: Server.java public class Server extends Thread { private boolean isRunning; private final

我正在努力实现服务器和客户端线程子类(模拟)之间的完美通信。我读了很多文章,但我想我还没有掌握如何同步线程的基本概念

问题:
我的服务器正在接收来自所有三个客户端的请求,关闭后,客户端将打印从服务器收到的回复。但服务器应该首先响应客户机,然后从其他线程获得另一个请求。 我们将非常感谢你的帮助。谢谢

以下是所涉及的课程:
Server.java

public class Server extends Thread {
private boolean isRunning;
private final Map < String, List < String > > content;
private final Queue < Request > requestQueue;

public Server(String name) {
    super(name);

    isRunning = true;
    content = new HashMap < > ();
    generateContent();
    requestQueue = new LinkedList < > ();

    Timer timer = new Timer();
    TimerTask timerTask = new TimerTask() {
        @Override public void run() {
            Runner.logf("Timer    : Server shutting down...%n");

            isRunning = false;

            timer.cancel();
        }
    };

    timer.schedule(timerTask, 10 * 1000);

    start();
}

public synchronized boolean acceptRequest(Request request) {
    if (isRunning) {
        try {
            Field privateClient = Request.class.getDeclaredField("client");
            privateClient.setAccessible(true);
            Client tClient = (Client) privateClient.get(request);

            requestQueue.add(request);
            Runner.logf("Server accepted Request : %s\n", request.toString());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    return false;
}

@Override public void run() {

    synchronized(this) {

        if (requestQueue.size() == 0) {
            Runner.logf("Server   : Request queue is empty, waiting...\n");
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        while (requestQueue.size() != 0) {
            Runner.logf("Server   : Has just been notified, getting back to work...\n");
            Request temp = requestQueue.poll();

            try {
                Field privateClient = Request.class.getDeclaredField("client");
                privateClient.setAccessible(true);
                Client tClient = (Client) privateClient.get(temp);

                Field privateMethod = Request.class.getDeclaredField("method");
                privateMethod.setAccessible(true);
                String tMethod = (String) privateMethod.get(temp);

                Field privateUri = Request.class.getDeclaredField("uri");
                privateUri.setAccessible(true);
                String tUri = (String) privateUri.get(temp);

                Field privateParameter = Request.class.getDeclaredField("parameter");
                privateParameter.setAccessible(true);
                String tParameter = (String) privateParameter.get(temp);

                List < String > tContent = content.get(tUri);

                if (tContent == null && tUri.compareTo("Index") != 0) {
                    tUri = "404";
                }


                if (tMethod.compareTo("GET") == 0) {
                    if (tUri.compareTo("Index") == 0) {
                        tContent = getKeys();
                        tUri = "Document";
                    }

                    Reply tRep = new Reply(tUri, tContent);
                    tClient.acceptReply(tRep);
                }

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }

}

private void generateContent() {
    String key;
    List < String > value;

    key = "A";
    value = new ArrayList < > ();
    value.add("A1");
    value.add("A2");
    content.put(key, value);
    key = "B";
    value = new ArrayList < > ();
    value.add("B1");
    value.add("B2");
    content.put(key, value);
    key = "C";
    value = new ArrayList < > ();
    value.add("C1");
    value.add("C2");
    content.put(key, value);
    key = "D";
    value = new ArrayList < > ();
    value.add("D1");
    value.add("D2");
    content.put(key, value);
}

private List < String > getKeys() {
    List < String > keys = new LinkedList < String > ();
    for (String k: content.keySet()) {
        keys.add(k);
    }
    return keys;
}
}
public class Client extends Thread {

private final Server server;
private final int periodOfRequests;
private final Random random;
private boolean firstRun;

public Client(String name, double frequencyOfRequests, Server server) {
    super(name);
    firstRun = true;
    this.server = server;
    this.periodOfRequests = (int)(1000.0 / frequencyOfRequests);
    this.random = new Random();

    start();
}

public synchronized void acceptReply(Reply reply) throws Exception {
    Runner.logf("%s : Got Reply %s\n", this.getName(), reply.toString());
}

@Override public void run() {
    Request req = null;

    synchronized(server) {


        if (firstRun) {
            firstRun = false;
            Request firstReq = new Request(this, "GET", "Index", "NA");
            Runner.logf("%s : Sent Request %s \n", this.getName(), firstReq);
            server.acceptRequest(firstReq);
            server.notify();
        }

        do {

            try {
                Thread.sleep(periodOfRequests);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            req = new Request(this, "GET", "A", "NA");
            Runner.logf("%s : Sent Request %s\n", this.getName(), req);
            server.notify();
        } while (server.acceptRequest(req));

    }
}
}
public class Runner
{

  private static final SimpleDateFormat sdf = new SimpleDateFormat( "HH:mm:ss.SSS " ) ;

  public static synchronized void logf ( String format , Object ... args )
  {
    System.out.print ( sdf.format( new Date() )) ;
    System.out.printf( format , args            ) ;
  }

  public static void main ( String[] args )
  {
    if ( args.length == 0 )  { args = new String [] { "1" , "2" , "0.5" } ; }

    Server server = new Server( "Server  " ) ;

    for ( int i = 0 ; i < args.length ; i++ )
    {
      String name      = String.format     ( "Client%02d" , i+1 ) ;
      double frequency = Double.parseDouble( args[i]            ) ;

      new Client( name , frequency , server ) ;
    }
  }
}
04:40:23.522 Server   : Request queue is empty, waiting...
04:40:23.522 Client01 : Sent Request [Client01:GET:Index:NA] 
04:40:23.522 Server accepted Request : [Client01:GET:Index:NA]
04:40:24.522 Client01 : Sent Request [Client01:GET:A:NA]
04:40:24.523 Server accepted Request : [Client01:GET:A:NA]
04:40:25.525 Client01 : Sent Request [Client01:GET:A:NA]
04:40:25.526 Server accepted Request : [Client01:GET:A:NA]......
07:12:18.688 Server   : Request queue is empty, waiting...
07:12:19.204 Client02 : Sent request [Client02:Get:Index:NA]
07:12:19.204 Server   : Has just been notified, getting back to work...
07:12:19.204 Server   : Request [Client02:Get:Index:NA] is VALID, handling...
07:12:19.204 Client02 : Got reply [Index:A,B,C,D]
07:12:19.204 Server   : Request queue is empty, waiting...
Runner.java

public class Server extends Thread {
private boolean isRunning;
private final Map < String, List < String > > content;
private final Queue < Request > requestQueue;

public Server(String name) {
    super(name);

    isRunning = true;
    content = new HashMap < > ();
    generateContent();
    requestQueue = new LinkedList < > ();

    Timer timer = new Timer();
    TimerTask timerTask = new TimerTask() {
        @Override public void run() {
            Runner.logf("Timer    : Server shutting down...%n");

            isRunning = false;

            timer.cancel();
        }
    };

    timer.schedule(timerTask, 10 * 1000);

    start();
}

public synchronized boolean acceptRequest(Request request) {
    if (isRunning) {
        try {
            Field privateClient = Request.class.getDeclaredField("client");
            privateClient.setAccessible(true);
            Client tClient = (Client) privateClient.get(request);

            requestQueue.add(request);
            Runner.logf("Server accepted Request : %s\n", request.toString());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    return false;
}

@Override public void run() {

    synchronized(this) {

        if (requestQueue.size() == 0) {
            Runner.logf("Server   : Request queue is empty, waiting...\n");
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        while (requestQueue.size() != 0) {
            Runner.logf("Server   : Has just been notified, getting back to work...\n");
            Request temp = requestQueue.poll();

            try {
                Field privateClient = Request.class.getDeclaredField("client");
                privateClient.setAccessible(true);
                Client tClient = (Client) privateClient.get(temp);

                Field privateMethod = Request.class.getDeclaredField("method");
                privateMethod.setAccessible(true);
                String tMethod = (String) privateMethod.get(temp);

                Field privateUri = Request.class.getDeclaredField("uri");
                privateUri.setAccessible(true);
                String tUri = (String) privateUri.get(temp);

                Field privateParameter = Request.class.getDeclaredField("parameter");
                privateParameter.setAccessible(true);
                String tParameter = (String) privateParameter.get(temp);

                List < String > tContent = content.get(tUri);

                if (tContent == null && tUri.compareTo("Index") != 0) {
                    tUri = "404";
                }


                if (tMethod.compareTo("GET") == 0) {
                    if (tUri.compareTo("Index") == 0) {
                        tContent = getKeys();
                        tUri = "Document";
                    }

                    Reply tRep = new Reply(tUri, tContent);
                    tClient.acceptReply(tRep);
                }

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }

}

private void generateContent() {
    String key;
    List < String > value;

    key = "A";
    value = new ArrayList < > ();
    value.add("A1");
    value.add("A2");
    content.put(key, value);
    key = "B";
    value = new ArrayList < > ();
    value.add("B1");
    value.add("B2");
    content.put(key, value);
    key = "C";
    value = new ArrayList < > ();
    value.add("C1");
    value.add("C2");
    content.put(key, value);
    key = "D";
    value = new ArrayList < > ();
    value.add("D1");
    value.add("D2");
    content.put(key, value);
}

private List < String > getKeys() {
    List < String > keys = new LinkedList < String > ();
    for (String k: content.keySet()) {
        keys.add(k);
    }
    return keys;
}
}
public class Client extends Thread {

private final Server server;
private final int periodOfRequests;
private final Random random;
private boolean firstRun;

public Client(String name, double frequencyOfRequests, Server server) {
    super(name);
    firstRun = true;
    this.server = server;
    this.periodOfRequests = (int)(1000.0 / frequencyOfRequests);
    this.random = new Random();

    start();
}

public synchronized void acceptReply(Reply reply) throws Exception {
    Runner.logf("%s : Got Reply %s\n", this.getName(), reply.toString());
}

@Override public void run() {
    Request req = null;

    synchronized(server) {


        if (firstRun) {
            firstRun = false;
            Request firstReq = new Request(this, "GET", "Index", "NA");
            Runner.logf("%s : Sent Request %s \n", this.getName(), firstReq);
            server.acceptRequest(firstReq);
            server.notify();
        }

        do {

            try {
                Thread.sleep(periodOfRequests);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            req = new Request(this, "GET", "A", "NA");
            Runner.logf("%s : Sent Request %s\n", this.getName(), req);
            server.notify();
        } while (server.acceptRequest(req));

    }
}
}
public class Runner
{

  private static final SimpleDateFormat sdf = new SimpleDateFormat( "HH:mm:ss.SSS " ) ;

  public static synchronized void logf ( String format , Object ... args )
  {
    System.out.print ( sdf.format( new Date() )) ;
    System.out.printf( format , args            ) ;
  }

  public static void main ( String[] args )
  {
    if ( args.length == 0 )  { args = new String [] { "1" , "2" , "0.5" } ; }

    Server server = new Server( "Server  " ) ;

    for ( int i = 0 ; i < args.length ; i++ )
    {
      String name      = String.format     ( "Client%02d" , i+1 ) ;
      double frequency = Double.parseDouble( args[i]            ) ;

      new Client( name , frequency , server ) ;
    }
  }
}
04:40:23.522 Server   : Request queue is empty, waiting...
04:40:23.522 Client01 : Sent Request [Client01:GET:Index:NA] 
04:40:23.522 Server accepted Request : [Client01:GET:Index:NA]
04:40:24.522 Client01 : Sent Request [Client01:GET:A:NA]
04:40:24.523 Server accepted Request : [Client01:GET:A:NA]
04:40:25.525 Client01 : Sent Request [Client01:GET:A:NA]
04:40:25.526 Server accepted Request : [Client01:GET:A:NA]......
07:12:18.688 Server   : Request queue is empty, waiting...
07:12:19.204 Client02 : Sent request [Client02:Get:Index:NA]
07:12:19.204 Server   : Has just been notified, getting back to work...
07:12:19.204 Server   : Request [Client02:Get:Index:NA] is VALID, handling...
07:12:19.204 Client02 : Got reply [Index:A,B,C,D]
07:12:19.204 Server   : Request queue is empty, waiting...
我想要实现的目标:

public class Server extends Thread {
private boolean isRunning;
private final Map < String, List < String > > content;
private final Queue < Request > requestQueue;

public Server(String name) {
    super(name);

    isRunning = true;
    content = new HashMap < > ();
    generateContent();
    requestQueue = new LinkedList < > ();

    Timer timer = new Timer();
    TimerTask timerTask = new TimerTask() {
        @Override public void run() {
            Runner.logf("Timer    : Server shutting down...%n");

            isRunning = false;

            timer.cancel();
        }
    };

    timer.schedule(timerTask, 10 * 1000);

    start();
}

public synchronized boolean acceptRequest(Request request) {
    if (isRunning) {
        try {
            Field privateClient = Request.class.getDeclaredField("client");
            privateClient.setAccessible(true);
            Client tClient = (Client) privateClient.get(request);

            requestQueue.add(request);
            Runner.logf("Server accepted Request : %s\n", request.toString());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    return false;
}

@Override public void run() {

    synchronized(this) {

        if (requestQueue.size() == 0) {
            Runner.logf("Server   : Request queue is empty, waiting...\n");
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        while (requestQueue.size() != 0) {
            Runner.logf("Server   : Has just been notified, getting back to work...\n");
            Request temp = requestQueue.poll();

            try {
                Field privateClient = Request.class.getDeclaredField("client");
                privateClient.setAccessible(true);
                Client tClient = (Client) privateClient.get(temp);

                Field privateMethod = Request.class.getDeclaredField("method");
                privateMethod.setAccessible(true);
                String tMethod = (String) privateMethod.get(temp);

                Field privateUri = Request.class.getDeclaredField("uri");
                privateUri.setAccessible(true);
                String tUri = (String) privateUri.get(temp);

                Field privateParameter = Request.class.getDeclaredField("parameter");
                privateParameter.setAccessible(true);
                String tParameter = (String) privateParameter.get(temp);

                List < String > tContent = content.get(tUri);

                if (tContent == null && tUri.compareTo("Index") != 0) {
                    tUri = "404";
                }


                if (tMethod.compareTo("GET") == 0) {
                    if (tUri.compareTo("Index") == 0) {
                        tContent = getKeys();
                        tUri = "Document";
                    }

                    Reply tRep = new Reply(tUri, tContent);
                    tClient.acceptReply(tRep);
                }

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }

}

private void generateContent() {
    String key;
    List < String > value;

    key = "A";
    value = new ArrayList < > ();
    value.add("A1");
    value.add("A2");
    content.put(key, value);
    key = "B";
    value = new ArrayList < > ();
    value.add("B1");
    value.add("B2");
    content.put(key, value);
    key = "C";
    value = new ArrayList < > ();
    value.add("C1");
    value.add("C2");
    content.put(key, value);
    key = "D";
    value = new ArrayList < > ();
    value.add("D1");
    value.add("D2");
    content.put(key, value);
}

private List < String > getKeys() {
    List < String > keys = new LinkedList < String > ();
    for (String k: content.keySet()) {
        keys.add(k);
    }
    return keys;
}
}
public class Client extends Thread {

private final Server server;
private final int periodOfRequests;
private final Random random;
private boolean firstRun;

public Client(String name, double frequencyOfRequests, Server server) {
    super(name);
    firstRun = true;
    this.server = server;
    this.periodOfRequests = (int)(1000.0 / frequencyOfRequests);
    this.random = new Random();

    start();
}

public synchronized void acceptReply(Reply reply) throws Exception {
    Runner.logf("%s : Got Reply %s\n", this.getName(), reply.toString());
}

@Override public void run() {
    Request req = null;

    synchronized(server) {


        if (firstRun) {
            firstRun = false;
            Request firstReq = new Request(this, "GET", "Index", "NA");
            Runner.logf("%s : Sent Request %s \n", this.getName(), firstReq);
            server.acceptRequest(firstReq);
            server.notify();
        }

        do {

            try {
                Thread.sleep(periodOfRequests);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            req = new Request(this, "GET", "A", "NA");
            Runner.logf("%s : Sent Request %s\n", this.getName(), req);
            server.notify();
        } while (server.acceptRequest(req));

    }
}
}
public class Runner
{

  private static final SimpleDateFormat sdf = new SimpleDateFormat( "HH:mm:ss.SSS " ) ;

  public static synchronized void logf ( String format , Object ... args )
  {
    System.out.print ( sdf.format( new Date() )) ;
    System.out.printf( format , args            ) ;
  }

  public static void main ( String[] args )
  {
    if ( args.length == 0 )  { args = new String [] { "1" , "2" , "0.5" } ; }

    Server server = new Server( "Server  " ) ;

    for ( int i = 0 ; i < args.length ; i++ )
    {
      String name      = String.format     ( "Client%02d" , i+1 ) ;
      double frequency = Double.parseDouble( args[i]            ) ;

      new Client( name , frequency , server ) ;
    }
  }
}
04:40:23.522 Server   : Request queue is empty, waiting...
04:40:23.522 Client01 : Sent Request [Client01:GET:Index:NA] 
04:40:23.522 Server accepted Request : [Client01:GET:Index:NA]
04:40:24.522 Client01 : Sent Request [Client01:GET:A:NA]
04:40:24.523 Server accepted Request : [Client01:GET:A:NA]
04:40:25.525 Client01 : Sent Request [Client01:GET:A:NA]
04:40:25.526 Server accepted Request : [Client01:GET:A:NA]......
07:12:18.688 Server   : Request queue is empty, waiting...
07:12:19.204 Client02 : Sent request [Client02:Get:Index:NA]
07:12:19.204 Server   : Has just been notified, getting back to work...
07:12:19.204 Server   : Request [Client02:Get:Index:NA] is VALID, handling...
07:12:19.204 Client02 : Got reply [Index:A,B,C,D]
07:12:19.204 Server   : Request queue is empty, waiting...

我认为您需要的是将整个
服务器
run()
方法放入一个循环中:

@Override
public void run() {
    synchronized (...) {
        while (isRunning) {
            //
            // (check the Queue...process requests)
            //
        }
    }
}
我假设您需要为您的
客户机
类执行相同的操作

现在,
Server
检查队列一次,然后
run
方法返回,线程死亡

此外:

  • 您不应该在
    线程
    的实例上使用
    同步
    /
    等待
    /
    通知
    /等<代码>线程
将监视器本身用于其他内容,如:

此实现使用
This.wait
循环调用
This.isAlive
。当线程终止
时,调用此.notifyAll
方法。建议应用程序不要在
线程
实例上使用
等待
通知
通知所有

相反,创建一个对象字段,如
private final object monitor=new object()然后在此基础上进行同步。制作一个getter,这样您的
客户机
类就可以访问它,但他们可能不需要访问它。您可能应该只放置
monitor.notify()
acceptRequest
方法中

  • 为什么要使用反射来访问请求上的私有字段,例如
    请求
    ??只要做一个吸气剂


  • 格式是怎么回事?我无法阅读此内容。@shmosel我刚刚用正确的格式更新了问题。我按照您的指示,耐心地解决了我的问题,现在线程可以正常通信。只是一个小问题,当服务器已经关闭并将其状态记录到控制台时,所有三个客户端都会再发送一个请求,程序不会终止。你能帮忙吗?