Using ThreadPoolExecutor and DiscardPolicy
Asked Answered
L

1

3

I need to make a client queue with ThreadPoolExecutor and an ability to drop clients if it exceeds some number (5 for example). It is kinda DDOS protection. When client #6 is requesting my server - it got dropped, etc. I got my server and client code, but I don't know how to realize ThreadPoolExecutor and DiscardPolicy. Ideas or examples?

Simple server:

   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);
        }

        }

    }

And a simple client:

  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!");

        }

    }
Lardaceous answered 18/5, 2015 at 9:41 Comment(0)
B
4

Use ThreadPoolExecutor with DiscardPolicy as below:

  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());
}

Rejected tasks:

New tasks submitted in method execute(Runnable) will be rejected when the Executor has been shut down, and also when the Executor uses finite bounds for both maximum threads and work queue capacity, and is saturated.

In either case, the execute method invokes the RejectedExecutionHandler.rejectedExecution(Runnable, ThreadPoolExecutor) method of its RejectedExecutionHandler.

Four predefined handler policies are provided:

1.ThreadPoolExecutor.AbortPolicy 2.ThreadPoolExecutor.CallerRunsPolicy 3.ThreadPoolExecutor.DiscardPolicy 4.ThreadPoolExecutor.DiscardOldestPolicy

Have a look at this documentation page for more details

If above four does not serve your purpose, you can write custom RejectionHandler by extending RejectedExecutionHandler.

I have used custom handler when I need to know which task is getting rejected and persist these failures either in disk or database.

Bugeye answered 29/2, 2016 at 3:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.