A simple java multithreading example, java Multithreading

Source: Internet
Author: User

A simple java multithreading example, java Multithreading

Now there is a task with a list of mobile phone numbers (20 W) and a list of phone numbers (10 W). We need to calculate which phone numbers are not listed in the phone list, which phone numbers appear more than once in the ticket.

The most direct method of thinking is to traverse two layers of loops. Although this method is stupid, there is no better way yet.

At the beginning, a single thread is used for processing. The code is not reconstructed with handwriting, but a simple description is provided:

package tool;import java.util.List;public class SingleThread{public static void main(String[] args){SingleThread st = new SingleThread();String userIdPath = "D:\\shell\\store_bak\\tool\\userid.txt";List<String> userIds = Util.readUserId(userIdPath);List<String> cdrItems = Util.readCdrItem();st.process(userIds, cdrItems);}/** *  * @param userIds * @param cdrItems */private void process(List<String> userIds, List<String> cdrItems){long startTime = System.currentTimeMillis();int count = 0;for (String key : userIds){String[] uninKeys = key.split("\\s+");count = 0;for (String cdr : cdrItems){if (cdr.contains("|" + uninKeys[0] + "|")&& cdr.contains("|" + uninKeys[1] + "|")){count++;}}}System.out.println((System.currentTimeMillis() - startTime) / 1000);}}

The code in Util is not given, that is, a simple file read operation. The whole process is not processed too quickly, and the most time-consuming operation is on the contains method, at the beginning, instead of using the contains method, we used regular expression matching. The results showed that the regular expression is not efficient, so we used the contains method instead. However, the efficiency is still unsatisfactory. Therefore, multithreading is used for processing.

Unlike traditional producer consumers, there are actually only consumers here. Because the raw data is almost time-consuming, the easiest way to think of is to define a shared index, the index is a shared variable and needs to be synchronized. Use the AtomicInteger provided in jdk directly. The Code is as follows:

package tool;import java.util.List;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.atomic.AtomicInteger;public class MutiThread{private static AtomicInteger lock = new AtomicInteger(0);public static void main(String[] args){MutiThread tool = new MutiThread();String userIdPath = "D:\\shell\\store_bak\\tool\\userid.txt";List<String> userIds = Util.readUserId(userIdPath);List<String> cdrItems = Util.readCdrItem();tool.work2(lock, userIds, cdrItems);}public void work2(AtomicInteger lock, List<String> userIds,List<String> cdrItems){final long startTime = System.currentTimeMillis();CyclicBarrier cb = new CyclicBarrier(5, new Runnable(){@Overridepublic void run(){System.out.println((System.currentTimeMillis() - startTime) / 1000);}});for (int i = 0; i < 5; i++){new Thread(new Worker(userIds, cdrItems, lock, cb)).start();}}class Worker implements Runnable{private List<String> userIds;private List<String> cdrItems;private AtomicInteger lock;private CyclicBarrier cb;public Worker(List<String> userIds, List<String> cdrItems,AtomicInteger lock, CyclicBarrier cb){this.userIds = userIds;this.cdrItems = cdrItems;this.lock = lock;this.cb = cb;}@Overridepublic void run(){while (true){int index = lock.getAndIncrement();if (index >= userIds.size())break;String id = userIds.get(index);process1(id, cdrItems);}try{cb.await();} catch (InterruptedException e){e.printStackTrace();} catch (BrokenBarrierException e){e.printStackTrace();}}}private void process1(String id, List<String> cdrItems){String[] uninKeys = id.split("\\s+");int count = 0;for (String cdr : cdrItems){if (cdr.contains("|" + uninKeys[0] + "|")&& cdr.contains("|" + uninKeys[1] + "|")){count++;}}}}

The use of Multithreading can indeed improve the efficiency, especially when the data volume is large, at least twice the speed. The larger the number of threads, the better, because JVM Scheduling on threads also consumes resources.

In this scenario, considering the implementation of concurrenthashmap, We can segment resources to avoid the use of multi-threaded resources. Therefore, we can divide the list into different segments, the Code is as follows:

package tool;import java.util.List;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.atomic.AtomicInteger;public class MutiSegmentMutiThread{private static AtomicInteger lock = new AtomicInteger(0);private static int ThreadNum = 10;public static void main(String[] args){MutiSegmentMutiThread tool = new MutiSegmentMutiThread();String userIdPath = "D:\\shell\\store_bak\\tool\\userid.txt";List<String> userIds = Util.readUserId(userIdPath);List<String> cdrItems = Util.readCdrItem();tool.work2(lock, userIds, cdrItems);}public void work2(AtomicInteger lock, List<String> userIds,List<String> cdrItems){final long startTime = System.currentTimeMillis();CyclicBarrier cb = new CyclicBarrier(ThreadNum, new Runnable(){@Overridepublic void run(){System.out.println((System.currentTimeMillis() - startTime) / 1000);}});int segmentSize = userIds.size() / ThreadNum;int start = 0;int end = 0;for (int i = 0; i < ThreadNum; i++){start = i * segmentSize;if (i == ThreadNum - 1){end = userIds.size();} else{end = (i + 1) * segmentSize;}new Thread(new Worker(userIds, cdrItems, cb, start, end)).start();}}class Worker implements Runnable{private List<String> userIds;private List<String> cdrItems;private CyclicBarrier cb;private int start;private int end;public Worker(List<String> userIds, List<String> cdrItems,CyclicBarrier cb, int start, int end){this.userIds = userIds;this.cdrItems = cdrItems;this.cb = cb;this.start = start;this.end = end;}@Overridepublic void run(){for (int i = start; i < end; i++){String id = userIds.get(i);process1(id, cdrItems);}try{cb.await();} catch (InterruptedException e){e.printStackTrace();} catch (BrokenBarrierException e){e.printStackTrace();}}}private void process1(String id, List<String> cdrItems){String[] uninKeys = id.split("\\s+");int count = 0;for (String cdr : cdrItems){if (cdr.contains("|" + uninKeys[0] + "|")&& cdr.contains("|" + uninKeys[1] + "|")){count++;}}}}

In practice, the third method is faster than the second method, but the improvement is not obvious. The above Code only provides an idea to solve the problem and must be able to continue optimization. If the data volume is large, you can consider using distributed computing.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.