【问题标题】:Using ThreadPoolExecutor and DiscardPolicy使用 ThreadPoolExecutor 和 DiscardPolicy
【发布时间】:2015-07-29 18:08:26
【问题描述】:

我需要使用 ThreadPoolExecutor 创建一个客户端队列,并且如果它超过某个数量(例如 5 个)就可以丢弃客户端。这有点像 DDOS 保护。当客户端 #6 请求我的服务器时 - 它被丢弃了,等等。我得到了我的服务器和客户端代码,但我不知道如何实现 ThreadPoolExecutor 和 DiscardPolicy。想法或例子?

简单服务器:

   import java.io.IOException;
    import java.io.InputStream;
    import java.io.ObjectInputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Semaphore;
    import java.util.logging.Level;
    import java.util.logging.Logger;

    public class Server {

    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {

        ServerSocket server = new ServerSocket (3000);

        ExecutorService es = Executors.newFixedThreadPool(2);

        Semaphore semaphore = new Semaphore (2);

        while(true){

        semaphore.acquire();

        Socket accept2 = server.accept();

        es.execute(()->{
            try (Socket accept = accept2) {
            serve(accept);
            } catch (Exception exception) {
                Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, exception);
            } 
            finally {
                semaphore.release();

            }
        });        

        }

    }

    private static void serve(final Socket accept) throws ClassNotFoundException, IOException {
        InputStream inputStream = accept.getInputStream();
        OutputStream outputStream = accept.getOutputStream();

        ObjectInputStream inputStream2 = new ObjectInputStream (inputStream);

        while (true){
            Object readObject = inputStream2.readObject();
            System.out.println(readObject);
        }

        }

    }

还有一个简单的客户端:

  import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.net.Socket;

    public class Client {

    public static void main(String[] args) throws IOException, InterruptedException {
        Socket socket = new Socket ("localhost", 3000);
        ObjectOutputStream oos = new ObjectOutputStream (
                socket.getOutputStream());
        oos.writeObject("First!");
        Thread.sleep(10000);
        oos.writeObject("First again!");
        Thread.sleep(10000);
        oos.writeObject("First again again!");

        }

    }

【问题讨论】:

    标签: java client server threadpoolexecutor ddos


    【解决方案1】:

    使用ThreadPoolExecutorDiscardPolicy 如下:

      int poolSize=1;
      int maxPoolSize=2;
      int queueSize=5;
      long aliveTive=1000;
      ArrayBlockingQueue<Runnable> queue= new ArrayBlockingQueue<Runnable>(queueSize);
      ThreadPoolExecutor executor= new ThreadPoolExecutor(poolSize,maxPoolSize,aliveTive,
                        TimeUnit.MILLISECONDS,queue,new ThreadPoolExecutor.DiscardPolicy());
    }
    

    被拒绝的任务:

    当 Executor 已经关闭,以及 Executor 对最大线程和工作队列容量都使用有限的界限并且饱和时,在方法 execute(Runnable) 中提交的新任务将被拒绝。

    在任何一种情况下,execute 方法都会调用其RejectedExecutionHandlerRejectedExecutionHandler.rejectedExecution(Runnable, ThreadPoolExecutor) 方法。

    提供了四个预定义的处理程序策略:

    1. 在默认的ThreadPoolExecutor.AbortPolicy 中,处理程序在拒绝时抛出运行时 RejectedExecutionException。
    2. ThreadPoolExecutor.CallerRunsPolicy 中,调用execute 的线程自己运行任务。这提供了一种简单的反馈控制机制,可以减慢新任务的提交速度。
    3. ThreadPoolExecutor.DiscardPolicy 中,简单地丢弃了一个无法执行的任务。
    4. ThreadPoolExecutor.DiscardOldestPolicy中,如果executor没有关闭,工作队列头部的任务被丢弃,然后重试执行(可能再次失败,导致重复。)

    查看此documentation 页面了解更多详情

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      • 2017-06-20
      • 2012-02-19
      • 1970-01-01
      • 2020-07-02
      相关资源
      最近更新 更多