This series of Java-related written interview knowledge, several other articles are as follows: Java written examination questions finishing Eighth wave
The seventh wave of the Java written test face
The sixth wave of the Java written test face
Java Written examination questions finishing five wave
Java written test face to organize the four waves
The third wave of the Java written test face
The second wave of the Java written test face
The first wave of the Java written test face
1, thread pool ThreadPool relatedUnder the Java.util.concurrent package, a series of classes related to the thread pool are provided. Reasonable use of the thread pool can bring several benefits: (1) reduce resource consumption. Reduce the consumption caused by thread creation and destruction by reusing created threads, (2) Increase response speed. When a task arrives, the task can be executed immediately without waiting for the thread to be created, (3) to increase the manageability of the thread. Thread is a scarce resource, if unlimited creation, will not only consume system resources, but also reduce the stability of the system, the use of thread pool can be unified allocation, tuning and monitoring.
The thread pool can respond to sudden bursts of traffic, reducing the time required to create and destroy threads through a finite number of fixed threads for a large amount of operational service.
Relationship to thread execution, threads pool-related classes as shown in figure:
We typically obtain a threadpoolexecutor thread pool or static method (such as Newscheduledthreadpool () by means of a static method (such as Newfixedthreadpool ()) Executors the tool class. ) to get the schedulethreadpoolexecutor thread pool. Use as follows: Executorservice threadpool= Executors.newfixedthreadpool (10); We have specified a 10-number fixed-thread pool, and there are many overloaded methods for getting thread pools, such as custom threadfactory to set more meaningful names for each thread created by executors. Executors creating a thread pool is the interior of new threadpoolexecutor or Schedulethreadpoolexecutor, which gives us a lot of default settings. As follows:
public static Executorservice newfixedthreadpool (int nthreads) {return
new Threadpoolexecutor (Nthreads, Nthreads,
0L, Timeunit.milliseconds,
new linkedblockingqueue<runnable> ());
Above through the Threadpoolexecutor construction method, for us to create a thread pool, many parameters executors tool class automatically configured for us. The following parameters are generally required to create a threadpoolexecutor thread pool:
public threadpoolexecutor (int corepoolsize, int maximumpoolsize, Long KeepAliveTime, timeunit unit, Blocki
Ngqueue<runnable> Workqueue, Threadfactory threadfactory, Rejectedexecutionhandler handler)
(1) corepoolsize (basic size of the thread pool): When a task is submitted to the thread pool, the line Cheng creates a thread to perform the task, even if other idle basic threads can perform new tasks, create threads, and no longer create a thread when the number of tasks to be performed is greater than the thread pool base size. If the Prestartallcorethreads method of the thread pool is invoked, the thread pool creates and starts all the base threads in advance. (2) maximumpoolsize (maximum thread pool size): The maximum number of threads that the thread pool allows to create. If the queue is full and the number of threads created is less than the maximum number of threads, the thread pool creates new threads to perform the task. It is worth noting that if you use the unbounded task queue This parameter has no effect. (3) KeepAliveTime (thread activity hold time): The thread pool's worker threads remain alive for as long as they are idle. So if you have a lot of tasks, and each task executes for a short time, you can increase the time and improve the utilization of the thread. (4) Timeunit (unit of thread activity retention time): The optional Unit has day (days), hours (HOURS), minutes (MINUTES), milliseconds (milliseconds), etc. (5) Workqueue (Task queue): A blocking queue that is used to hold tasks waiting to be performed. You can select several blocking queues: Arrayblockingqueue, Linkedblockingqueue, Synchronousqueue, Priorityblockingqueue (6) Threadfactory: The factory that is used to set up the creation thread can set a more meaningful name for each created thread through the thread factory. (7) handler (saturation strategy): When the queue and thread pool are full, indicating that the thread pool is saturated, then a policy must be taken to handle the new task submitted. This policy is abortpolicy by default, indicating that an exception is thrown when a new task cannot be processed.
We try to prioritize the use of static methods provided by executors to create a thread pool, and if executors provides a method that does not meet the requirements, then create it yourself through the Threadpoolexecutor class.
two ways to submit a task:(1) through the Execute () method, such as:
Executorservice threadpool= Executors.newfixedthreadpool (ten);
Threadpool.execute (New Runnable () {...});
This way the commit has no return value and cannot determine whether the task was successfully executed by the thread pool.
(2) through the Submit () method, such as:
future<?> Future = threadpool.submit (new Runnable () {...});
try {
Object res = Future.get ();
} catch (Interruptedexception e) {
//Handle Interrupt Exception
e.printstacktrace ();
} catch (Executionexception e) {
//handle Unable to perform task exception
e.printstacktrace ();
} finally{
//close thread pool
executor.shutdown ();
}
Using the Submit method to submit the task, it returns a future object that gets the return value through the future Get method, which blocks until the task completes, and uses a fetch (long timeout, timeunit unit) Method is blocked for a period of time and returns immediately, and it is possible that the task is not finished.
Thread Pooling Workflow analysis: (from reference articles)
As we can see from the above figure, when a new task is submitted to the thread pool, the process flow of the thread pool is as follows:
1, first thread pool to determine whether the basic thread pool is full (< Corepoolsize. )。 Not full, create a worker thread to perform the task. Full, then go to the next process.
2, the second thread pool to determine whether the work queue is full. is not full, the newly submitted task is stored in the work queue. Full, then go to the next process. 3, the last thread pool to determine whether the entire thread pool is full (< maximumpoolsize). )。 is not full, a new worker thread is created to perform the task, and when it is full, the saturation policy is given to handle the task.
In other words, the thread pool takes precedence over the number of threads that create the basic thread pool size (corepoolsize), and when that number is not reached, a new thread is created directly each time a new task is committed, and when the number of basic threads is reached, a new task arrives, placing precedence in the waiting queue, To create a new thread (cannot exceed the maximum number of thread pools maxmumpoolsize).
You can read the reference article about the configuration principles for the thread pool.
Threadpoolexecutor Simple example:
public class Bankcount {public
synchronized void Addmoney (int) {//Saving money
System.out.println ( Thread.CurrentThread (). GetName () + "> Deposit: + Money";
}
Public synchronized void Getmoney (int) {//Withdraw money
System.out.println (Thread.CurrentThread (). GetName () + "> Withdraw money: "+ Money);
}
}
Test class:
public class Banktest {public static void main (string[] args) {final Bankcount bankcount = new Bankcount ();
Executorservice executor = Executors.newfixedthreadpool (10);
Executor.execute (New Runnable () {//savings thread @Override public void Run () {int i = 5;
while (i--> 0) {bankcount.addmoney (200);
try {thread.sleep (500);
catch (Interruptedexception e) {e.printstacktrace ();
}
}
}
});
future<?> Future = executor.submit (new Runnable () {//Fetch money thread @Override public void run () {
int i = 5;
while (i--> 0) {try {thread.sleep (500);
catch (Interruptedexception e) {e.printstacktrace (); } Bankcount.getmoney (200);
}
}
});
try {Object res = future.get ();
System.out.println (RES);
catch (Interruptedexception e) {//Handle interrupt exception e.printstacktrace ();
The catch (Executionexception e) {//handle cannot perform task exception e.printstacktrace ();
}finally{//Close thread pool Executor.shutdown (); }
}
}
The results are as follows: Pool-1-thread-1> Deposit: pool-1-thread-1> Deposit: $ pool-1-thread-2>: $ pool-1-thread-1> Deposit: 200 Pool-1-thread-2> withdraw money: Pool-1-thread-1> into: pool-1-thread-2> withdraw money: pool-1-thread-1> Deposit: 200 Pool-1-thread-2> Withdraw money: pool-1-thread-2> withdraw money: null
As you can see, the printed future.get () Gets the result null, because runnable is not return value, need to return value to use callable, here is no longer detailed, can refer to the following article: http://blog.csdn.net/ xiaojin21cen/article/details/41820983
http://icgemu.iteye.com/blog/467848
2. Producer and Consumer modelsProducer consumer model, the description is: There is a buffer as a storehouse, the producer can put the product into the storehouse, the consumer can take away the product from the storehouse. The core of solving consumer and producer problems is to ensure the integrity of the same resource being accessed concurrently by multiple threads. Generally using signal or locking mechanism to solve. Here are three main ways to solve the problem of producer and consumer problems in Java:
(1) Wait ()/notify (), Notifyall ( )The wait and notify methods are two methods of object, so each class will have both methods. Wait () method: Leave the current thread in the waiting state, discard the lock, and let the other thread execute. Notify () Method: wakes up other threads waiting for the same lock, discards the lock, and waits. The following example:
/** * Warehouse/public class Storage {private static final int max_size = maximum capacity of 100;//warehouse private list<object>
data = new arraylist<object> ()//Storage carrier/** * Production operation/public synchronized void produce (int num) { if (data.size () + num > Max_size) {//If the production of these products will exceed the maximum capacity of the warehouse, the production operation is blocked System.out.println ("Number of production operations-->:" + num + ", beyond the warehouse capacity, production congestion.
------Inventory: "+ data.size ());
try {wait ();
catch (Interruptedexception e) {e.printstacktrace (); }//Here, indicating that the product can be produced normally for (int i = 0; i < num i++) {//Production num Data.add (new Object ())
;
System.out.println ("Production Operation--> Quantity:" + num + ", successfully warehousing ~------Inventory:" + data.size ());
After the production of products, wake up other waiting to consume the thread notify (); /** * Consumption operation/public synchronized void consume (int num) {if (data.size ()-num < 0) {//If the number of products Insufficient System.out.println ("Consumption operation--> Quantity:" + num + ", the stock is insufficient, the consumption is blocked.
------Inventory: "+ data.size ());
try {wait ();
catch (Interruptedexception e) {e.printstacktrace ();
(int i = 0; i < num; i++) {//consumer num data.remove (0), indicating that it can be consumed normally.
System.out.println ("Consumption operation--> Quantity:" + num + ", Consumption success ~------Inventory:" + data.size ());
After the consumption of products, wake up other waiting for production thread notify (); }
}
Producers:
public class Producer implements runnable{
private Storage Storage;
private int num;//How many public Producer per production
(Storage sto,int num) {
Storage = sto;
This.num = num;
}
@Override public
Void Run () {
storage.produce (num);
}
}
Consumers:
public class Consumer implements runnable{
private Storage Storage;
private int num;//How many public Consumer per consumption
(Storage sto,int num) {
Storage = sto;
This.num = num;
}
@Override public
Void Run () {
storage.consume (num);
}
}
Test class:
public class Storagetest {public static void main (string[] args) {Storage Storage = new St
Orage (); Executorservice tasksubmit = Executors.newfixedthreadpool (10);
To use the thread pool knowledge we summarized in the previous section///4 consumer Tasksubmit.submit (new Consumer (storage, 30));
Tasksubmit.submit (New Consumer (storage, 10));
Tasksubmit.submit (New Consumer (storage, 20));
Given 6 producers Tasksubmit.submit (new Producer (storage, 70));
Tasksubmit.submit (New Producer (storage, 10));
Tasksubmit.submit (New Producer (storage, 20));
Tasksubmit.submit (New Producer (storage, 10));
Tasksubmit.submit (New Producer (storage, 10));
Tasksubmit.submit (New Producer (storage, 10));
Tasksubmit.shutdown (); }
}
Print Result: Consumption operation--> Quantity: 30, the stock is insufficient, the consumption is blocked. ------Inventory: 0 Production Operations--> Quantity: 10, successfully warehousing ~------Inventory: 10 Production operations--> Quantity: 70, successfully warehousing ~------Inventory: 80 production Operations--> Quantity: 10, successfully warehousing ~------Inventory: 90 Production Operation--> Quantity: 10, successful warehousing ~------Inventory: 100 production Operation--> Quantity: 20, exceeding the warehouse capacity, production blocking. ------Inventory: 100 consumption operation--> Quantity: 10, Consumption success ~------Inventory: 90 Production Operation--> Quantity: 20, successful warehousing ~------Inventory: 110 Production Operation--> Quantity: 10, exceeding warehouse capacity, production blocking. ------Inventory: 110 consumption operation--> Quantity: 20, Consumption success ~------Inventory: 90 consumption Operation--> Quantity: 30, Consumption success ~------Inventory: 60 production Operation--> Quantity: 10, successful warehousing ~------Inventory: 70
In the warehouse, wake us up using notify () instead of using Notifyall () because here, if the test data is improperly set, it can easily cause deadlocks (such as waking up all production processes) because there is a flaw in the use of wait and notify: