Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 10)

javathread.jpeg

Worker Thread pattern

worker means "worker". In the WorkerThread pattern, ** worker threads ** go to get jobs one by one and process them. If there is no job, the worker thread waits for a new job. Worker Thread is sometimes called ** Background Thread **.

Consider the following example. A thread in the ClientThread class makes a job request to the Channel class. An instance of the Channel class has five worker threads. The worker thread is waiting for a job request. When a job request arrives, the worker thread receives one job request from Channel and processes it. When the process is finished, the worker thread returns to Channel and waits for the next request.

(See this manual for the entire code)

Main.java


public class Main { 
    public static void main(String[] args) { 
        Channel channel = new Channel(5);   //Create 5 worker threads
        channel.startWorkers(); //Start a worker thread
        new ClientThread("Alice", channel).start();  //Start a thread to make a job request
        new ClientThread("Bobby", channel).start(); 
        new ClientThread("Chris", channel).start(); 
    } 
}

ClientThread.java


public class ClientThread extends Thread { 
    ...
    public void run() { 
        try { 
            for (int i = 0; true; i++) { 
                Request request = new Request(getName(), i); 
                channel.putRequest(request);  //Make a job request
                Thread.sleep(random.nextInt(1000)); 
            } 
        } catch (InterruptedException e) { 
        } 
    } 
}

Channel.java


public class Channel { 
    private static final int MAX_REQUEST = 100; 
    private final Request[] requestQueue; 
    private int tail;
    private int head;
    private int count;
 
    private final WorkerThread[] threadPool; 
 
    public Channel(int threads) { 
        this.requestQueue = new Request[MAX_REQUEST]; 
        this.head = 0; 
        this.tail = 0; 
        this.count = 0; 
 
        threadPool = new WorkerThread[threads]; 
        for (int i = 0; i < threadPool.length; i++) { 
            threadPool[i] = new WorkerThread("Worker-" + i, this); 
        } 
    }

    public void startWorkers() { 
        for (int i = 0; i < threadPool.length; i++) { 
            threadPool[i].start(); 
        } 
    }

    public synchronized void putRequest(Request request) { 
        while (count >= requestQueue.length) { 
            try { 
                wait(); 
            } catch (InterruptedException e) { 
            } 
        } 
        requestQueue[tail] = request; 
        tail = (tail + 1) % requestQueue.length; 
        count++; 
        notifyAll(); 
    }

    public synchronized Request takeRequest() { 
        while (count <= 0) { 
            try { 
                wait(); 
            } catch (InterruptedException e) { 
            } 
        } 
        Request request = requestQueue[head]; 
        head = (head + 1) % requestQueue.length; 
        count--; 
        notifyAll(); 
        return request; 
    } 
}

WorkerThread.java


public class WorkerThread extends Thread { 
    ...
    public void run() { 
        while (true) { 
            Request request = channel.takeRequest(); //Go get a job
            request.execute(); 
        } 
    } 
}

The Channel class has a field called requestQueue for passing work requests. The putRequest method puts a request in this queue, and the takeRequest method retrieves it. Here, the Producer-Consumer pattern is used. The Thread-Per-Message pattern spawned a new thread each time it did a job. However, in the Worker Thread pattern, ** worker threads perform work repeatedly, so there is no need to start a new thread. ** WorkerThread has only an instance of Channel for you to get a job request, and doesn't know anything about the specific job.

Character

Client role The Client role creates a job request as a Request role and passes it to the Channel role. In the sample program, the ClientThread class played this role.

Channel role The Channel role receives the Request role from the Client role and passes it to the Worker role. In the sample program, the Channel class played this role.

Worker role The Worker role receives the Request role from the Channel role and executes the work. After work, go get the next Request role. In the sample program, the WorkerThread class played this role.

Request role The Request role is to represent a job. The Request role holds the information necessary to perform the task. In the sample program, the Request class played this role.

Tips for expanding your thoughts

Increased throughput Unlike the Thread-Per-Message pattern, one of the themes of the Worker Thread pattern is ** to reuse threads and recycle them to increase throughput **.

Capacity control The amount of services that can be provided at the same time is called capacity. The number of worker roles can be freely determined. In the sample program, this is the argument threads given to the Channel constructor. The more worker roles you have, the more work you can do in parallel, but preparing more worker roles than the number of jobs requested at the same time is useless and consumes more resources. The number of worker roles does not necessarily have to be set at startup, and can be changed dynamically. The Channel role holds the Request role. If the number of Request roles that can be held by the Channel role is large, the difference in processing speed between the Client role and the Worker role can be filled (buffered). However, a large amount of memory is consumed to hold the Request role. You can see that there is a ** capacity-resource trade-off ** here.

Separation of invocation and execution When making a normal method call, "method invocation" and "method execution" are performed in succession. ** In a normal method call, invocation and execution are inseparable **. However, ** Worker Thread patterns and Thread-Per-Message patterns separate method invocation and execution **. Invocation of a method is called invocation, and execution is called execution. ** Worker Thread pattern and Thread-Per-Message pattern can be said to separate method invocation and execution **. This has the following merits.

--Improved responsiveness Even if it takes a long time to execute, those who have invocation can proceed.

--Execution order control (scheduling) You can prioritize the Request role and control the order in which the Channgel role passes the Request role to the Worker role. This is called request ** scheduling **.

--Cancellable / Repeatable Although invocation was done, execution can realize a function called cancellation.

--Distributed processing It becomes easier to separate the computer to invoke and the computer to execute.

Polymorphic Request role For example, if you create a subclass of the Request class and pass its instance to Channel, WorkerThread will call execute for that instance without any problems. This can be described as utilizing ** polymorphism **. Since all the information necessary to execute the work is described in the Request role, even if a polymorphic Request role is created and the types of work are increased, the Channel role and the Worker role do not need to modify it. Even if the types of work increase, the Worker role still just calls the execute method of the Request role.


Relation Summary of "Design Patterns Learned in Java Language (Multithreaded Edition)" (Part 1) Summary of "Design Patterns Learned in Java Language (Multithreaded Edition)" (Part 2) Summary of "Design Patterns Learned in Java Language (Multithreaded Edition)" (Part 3) Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 4) Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 5) Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 6) Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 7) Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 8) Summary of "Design Patterns Learned in Java Language (Multithreaded Edition)" (Part 9)

Recommended Posts

Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 10)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 7)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 3)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 9)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 6)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 4)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 5)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 2)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 1)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 11)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 12)
Summary of "Design Patterns Learned in Java Language (Multithread Edition)" (Part 8)
[Java] Summary of design patterns
A quick review of Java learned in class part4
Summary of Java language basics
A quick review of Java learned in class part3
A quick review of Java learned in class part2
I read Hiroshi Yuki "Introduction to Design Patterns Learned in Java Language" (SB Creative)
Java Design Patterns
What I learned in Java (Part 2) What are variables?
A quick review of Java learned in class
Summary of what I learned in Spring Batch
Try design patterns in C language! Memento pattern-Let's memorize the memories of the data
[Java] Basic summary of Java not covered by Progate ~ Part 1 ~
What I learned in Java (Part 3) Instruction execution statement
Summary of how to implement default arguments in Java
Summary of Java support 2018
Java design pattern summary
What I learned in Java (Part 4) Conditional branching and repetition
[Java] Basic summary of Java not covered by Progate ~ Part 2 ยท List ~
Road to Java Engineer Part2 What kind of language is Java?
Read design patterns in Ruby
[Java11] Stream Summary -Advantages of Stream-
[Java] Summary of regular expressions
[Java] Summary of operators (operator)
[Java] Summary of for statements
Summary of Java Math class
Implementation of gzip in java
[Java] Summary of control syntax
Implementation of tri-tree in Java
Summary of java error processing
[Java] Summary of mathematical operations
What I have learned in Java (Part 1) Java development flow and overview
Summary of ORM "uroboroSQL" that can be used in enterprise Java
[For beginners] Summary of java constructor
Summary of [Java silver study] package
Basic usage of java Optional Part 1
thread safe process in java language
AtCoder 400 points algorithm summary (Java edition)
List of members added in Java 9
Creating lexical analysis in Java 8 (Part 2)
List of types added in Java 9
Summary of object-oriented programming using Java
Implementation of like function in Java
Creating lexical analysis in Java 8 (Part 1)