In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article is about how Java simulates concurrent requests. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.
It is naturally convenient to simulate concurrent requests in java, as long as you open a few more threads and initiate the request. However, this kind of request, generally there will be a start-up sequence, it is not really concurrent at the same time!
How can we achieve real simultaneous concurrency?
The point of this article is that locking CountDownLatch is provided in java, which is the most appropriate way to do this kind of thing.
All you need is:
Open n threads, add a lock, open all threads
When all threads are ready, press the open button and you can actually initiate concurrent requests.
Package com.test;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.util.concurrent.CountDownLatch Public class LatchTest {public static void main (String [] args) throws InterruptedException {Runnable taskTemp = new Runnable () {/ / Note, here is non-thread safe, leaving private int iCounter; @ Override public void run () {for (int I = 0; I < 10) ICounter +) {/ / initiate request / / HttpClientOp.doGet ("https://www.baidu.com/"); iCounter++; System.out.println (System.nanoTime () +" ["+ Thread.currentThread () .getName () +"] iCounter = "+ iCounter) Try {Thread.sleep;} catch (InterruptedException e) {e.printStackTrace ();}; LatchTest latchTest = new LatchTest (); latchTest.startTaskAllInOnce (5, taskTemp) } public long startTaskAllInOnce (int threadNums, final Runnable task) throws InterruptedException {final CountDownLatch startGate = new CountDownLatch (1); final CountDownLatch endGate = new CountDownLatch (threadNums); for (int I = 0; I < threadNums) ITunes +) {Thread t = new Thread () {public void run () {try {/ / causes the thread to wait here, and when the start door opens, it swarms into the startGate.await () Try {task.run ();} finally {/ / subtract the end door by 1, and when it is reduced to 0, you can open the end door endGate.countDown () }} catch (InterruptedException ie) {ie.printStackTrace ();}; t.start ();} long startTime = System.nanoTime () System.out.println (startTime + "[" + Thread.currentThread () + "] All thread is ready, concurrent going..."); / / since only one switch is needed to open the door, immediately open the start door startGate.countDown (); / / wait, the end door opens endGate.await (); long endTime = System.nanoTime () System.out.println (endTime + "[" + Thread.currentThread () + "] All thread is completed."); return endTime-startTime;}}
The execution effect is shown in the following figure:
For the httpClientOp tool class, you can use a mature toolkit or write a brief access method yourself, as shown below:
Class HttpClientOp {public static String doGet (String httpurl) {HttpURLConnection connection = null; InputStream is = null; BufferedReader br = null; String result = null;// returns the result string try {/ / create a remote url connection object URL url = new URL (httpurl) / / Open a connection through a remote url connection object and forcefully convert it to httpURLConnection class connection = (HttpURLConnection) url.openConnection (); / / set the connection method: get connection.setRequestMethod ("GET"); / / set the timeout for connecting to the host server: 15000 milliseconds connection.setConnectTimeout (15000) / / set the time to read the data returned remotely: 60000 milliseconds connection.setReadTimeout (60000); / / send the request connection.connect (); / / get the input stream if (connection.getResponseCode () = = 200) {is = connection.getInputStream () via connection connection / / encapsulate the input stream is and specify the character set br = new BufferedReader (new InputStreamReader (is, "UTF-8")); / / store data StringBuffer sbf = new StringBuffer (); String temp = null While ((temp = br.readLine ())! = null) {sbf.append (temp); sbf.append ("\ r\ n");} result = sbf.toString ();}} catch (MalformedURLException e) {e.printStackTrace () } catch (IOException e) {e.printStackTrace ();} finally {/ / close resource if (null! = br) {try {br.close ();} catch (IOException e) {e.printStackTrace () }} if (null! = is) {try {is.close ();} catch (IOException e) {e.printStackTrace ();}} connection.disconnect () / / close remote connection} return result;} public static String doPost (String httpUrl, String param) {HttpURLConnection connection = null; InputStream is = null; OutputStream os = null; BufferedReader br = null; String result = null; try {URL url = new URL (httpUrl) / / Open the connection through the remote url connection object connection = (HttpURLConnection) url.openConnection (); / / set the connection request method connection.setRequestMethod ("POST"); / / set the connection host server timeout: 15000 Ms connection.setConnectTimeout (15000) / / set the timeout for the data returned by the read host server: 60000 milliseconds connection.setReadTimeout (60000); / / default: false, which needs to be set to true connection.setDoOutput (true) when transferring data / writing data to the remote server / / the default value is: true. When reading data from the remote service, it is set to true, and this parameter is optional connection.setDoInput (true). / / set the format of the input parameter: the request parameter should be in the form of name1=value1&name2=value2. Connection.setRequestProperty ("Content-Type", "application/x-www-form-urlencoded"); / / set authentication information: Authorization: Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0 connection.setRequestProperty ("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0"); / / get an output stream os = connection.getOutputStream () through the connection object / / write out / transfer the parameters through the output stream object, which is os.write (param.getBytes ()) written through the byte array; / / get an input stream through the connection object and read if (connection.getResponseCode () = = 200) {is = connection.getInputStream () remotely. / / wrapping the input stream object: charset sets br = new BufferedReader (new InputStreamReader (is, "UTF-8")); StringBuffer sbf = new StringBuffer (); String temp = null according to the requirements of the work project group / / Loop through a row to read data while ((temp = br.readLine ())! = null) {sbf.append (temp); sbf.append ("\ r\ n");} result = sbf.toString () } catch (MalformedURLException e) {e.printStackTrace ();} catch (IOException e) {e.printStackTrace ();} finally {/ / close resource if (null! = br) {try {br.close () } catch (IOException e) {e.printStackTrace ();}} if (null! = os) {try {os.close ();} catch (IOException e) {e.printStackTrace () }} if (null! = is) {try {is.close ();} catch (IOException e) {e.printStackTrace () }} / / disconnect from the remote address url connection.disconnect ();} return result;}}
As above, you can initiate real concurrent requests.
The schematic diagram of the operation flow of concurrent requests is as follows:
A door is set here to ensure that all threads can take effect at the same time. However, the simultaneous startup here is only at the language level, and it is not absolutely concurrent at the same time. Specific calls also depend on the number of CPU, the number of threads and the operating system's thread scheduling functions, but we do not need to dwell on these, the focus is to understand the principle!
Similar to CountDownLatch, there is a tool fence CyclicBarrier, which also provides a tool fence that waits for all threads to arrive at a certain point, and then starts an action together, with the same effect, but the purpose of the fence is indeed relatively pure, that is, to wait for all threads to arrive. Although the lock-up CountDownLatch mentioned above is to start after all threads arrive, its trigger point is actually the last switch. So the focus is different.
Take a brief look at how fences are truly concurrent at the same time. Examples are as follows:
/ / consistent with locking structure public class LatchTest {public static void main (String [] args) throws InterruptedException {Runnable taskTemp = new Runnable () {private int iCounter; @ Override public void run () {/ / initiate request / / HttpClientOp.doGet ("https://www.baidu.com/"); iCounter++ System.out.println (System.nanoTime () + "+ Thread.currentThread (). GetName () +"] iCounter = "+ iCounter);}}; LatchTest latchTest = new LatchTest (); / / latchTest.startTaskAllInOnce (5, taskTemp); latchTest.startNThreadsByBarrier (5, taskTemp) } public void startNThreadsByBarrier (int threadNums, Runnable finishTask) throws InterruptedException {/ / sets the action when the fence is released, such as initializing some values CyclicBarrier barrier = new CyclicBarrier (threadNums, finishTask); / / starting n threads, which is consistent with the fence threshold, that is, when the number of thread preparations meets the requirements, the fence is just opened, thus achieving a unified control effect for (int I = 0; I < threadNums) Thread.sleep +) {Thread.sleep; new Thread (new CounterTask (barrier)). Start ();} System.out.println (Thread.currentThread (). GetName () + "out over...");}} class CounterTask implements Runnable {/ / into the fence, generally considering a more elegant way private CyclicBarrier barrier; public CounterTask (final CyclicBarrier barrier) {this.barrier = barrier } public void run () {System.out.println (Thread.currentThread (). GetName () + "-" + System.currentTimeMillis () + "is ready..."); try {/ / sets a fence so that the thread waiting here can open the gate barrier.await () when the thread arriving at the location meets the requirements;} catch (InterruptedException e) {e.printStackTrace () } catch (BrokenBarrierException e) {e.printStackTrace ();} System.out.println (Thread.currentThread () .getName () + "-" + System.currentTimeMillis () + "started...");}}
The running result is as follows:
Each has its own application scenario, the key lies in the demand.
Thank you for reading! This is the end of the article on "how Java simulates concurrent requests". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, you can share it for more people to see!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.