staticfinalint testTimes = 10000; // how many times we will do for benchmark staticfinallong seed = 345423533; // constant seed, for test only
staticvoidbenchmarkSingleThread(){ Random random = new Random(seed);
/* start benchmark */ long startTime = System.currentTimeMillis(); for (int i = 0; i < testTimes; i++) { result = null; // reset result val
int target = random.nextInt(bound);
getIndexOfNums(0, bound, target);
if (target != result) System.out.printf("expect: '%d', but got val '%d'", target, result); } long endTime = System.currentTimeMillis(); /* end benchmark */
staticvoidbenchmarkTwoThreadWithMessagePassing()throws InterruptedException, BrokenBarrierException { BlockingQueue<Integer> bQueue = new ArrayBlockingQueue<>(1); Random random = new Random(seed);
staticvoidbenchmarkSingleThread(){ Random random = new Random(seed);
/* start benchmark */ long startTime = System.currentTimeMillis(); for (int i = 0; i < testTimes; i++) { result = null; // reset result val
int target = random.nextInt(bound);
getIndexOfNums(0, bound, target);
if (target != result) System.out.printf("expect: '%d', but got val '%d'", target, result); } long endTime = System.currentTimeMillis(); /* end benchmark */
if (target != result) System.out.printf("expect: '%d', but got val '%d'", target, result); } long endTime = System.currentTimeMillis(); /* end benchmark */
// start all threads for (Thread thread : threads) thread.start();
/* start benchmark */ long startTime = System.currentTimeMillis(); for (int i = 0; i < testTimes; i++) { result = null; // reset result val
int target = random.nextInt(bound); for (BlockingQueue<Integer> bQueue : queues) { bQueue.put(target); }
getIndexOfNumsWithBarrier(tmp, bound, target);
if (target != result) System.out.printf("expect: '%d', but got val '%d'", target, result); } long endTime = System.currentTimeMillis(); /* end benchmark */
for (Thread thread : threads) thread.interrupt(); }
/** * get index of nums only when result is null * * @param start begin bound * @param end end bound * @param target target val */ staticvoidgetIndexOfNums(int start, int end, int target){ for (; start < end; start++) { if (result != null) return;
if (nums[start] == target) { result = start; return; } } }
static CyclicBarrier barrier = new CyclicBarrier(threadNum);
/** * just like getIndexOfNums, but will done together when one of two threads * found result * * @param start * @param end * @param target * @throws InterruptedException * @throws BrokenBarrierException */ staticvoidgetIndexOfNumsWithBarrier(int start, int end, int target) throws InterruptedException, BrokenBarrierException {
getIndexOfNums(start, end, target);
barrier.await(); return; } }
结论
慎用多线程
使用多线程时要考虑线程创建和计算机多线程间context切换时消耗的资源。 Sometimes, less is more.