Java Concurrency: Thread Introduction 博客分类: JavaSE TheadSleepJoin
程序员文章站
2024-03-25 15:36:22
...
1) Sleep
package edu.xmu.thread; public class SleepTest { public static void main(String[] args) { Thread thread1 = new Thread(new MyRunnable()); Thread thread2 = new Thread(new MyRunnable()); Thread thread3 = new Thread(new MyRunnable()); System.out.println(System.currentTimeMillis()); thread1.start(); thread2.start(); thread3.start(); System.out.println(System.currentTimeMillis()); } private static class MyRunnable implements Runnable { @Override public void run() { try { System.out.println(Thread.currentThread().getName() + " is going to sleep."); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }Output:
1400034838666 Thread-0 is going to sleep. 1400034838666 Thread-1 is going to sleep. Thread-2 is going to sleep. // We can see that static method Thread.sleep() will sleep the current thread.Attention:
System.out.println(System.currentTimeMillis()); thread1.start(); thread2.start(); thread3.start(); thread3.sleep(1000); System.out.println(System.currentTimeMillis()); // Output: //1400035177744 //Thread-0 is going to sleep. //Thread-1 is going to sleep. //Thread-2 is going to sleep. //1400035178744 // The thread3.sleep(1000); will not make thread3 sleep. // It will make current main thread sleep instead. // So we can find out that although threadInstance.sleep() is applicable, // it will make the current thread instead of threadInstance sleep. // Pay attention to this pitfall.
2) Join
Example below:
package edu.xmu.thread; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.List; public class ThreadTest { public static void main(String[] args) { List<CalculationThread> subThreadList = initSubThreadList(); List<Integer> numList = new ArrayList<Integer>(); for (CalculationThread calThread : subThreadList) { calThread.start(); // Start all calculation thread } try { System.out.println("Current Time Mills: " + Calendar.getInstance().getTimeInMillis()); for (CalculationThread calThread : subThreadList) { calThread.join(); } System.out.println("Current Time Mills: " + Calendar.getInstance().getTimeInMillis()); CalculationThread sumThread = new CalculationThread(); for (CalculationThread subThread : subThreadList) { numList.add(subThread.getSum()); } sumThread.setNumList(numList); sumThread.start(); sumThread.join(); System.out.println("Current Time Mills: " + Calendar.getInstance().getTimeInMillis()); System.out.println(sumThread.getSum()); } catch (InterruptedException e) { e.printStackTrace(); } } private static List<CalculationThread> initSubThreadList() { CalculationThread thread1 = new CalculationThread(Arrays.asList(200, 200, 200, 200)); CalculationThread thread2 = new CalculationThread(Arrays.asList(300, 300, 300, 300)); CalculationThread thread3 = new CalculationThread(Arrays.asList(300, 300, 300, 300)); CalculationThread thread4 = new CalculationThread(Arrays.asList(300, 300, 300, 300)); CalculationThread thread5 = new CalculationThread(Arrays.asList(300, 300, 300, 300)); List<CalculationThread> subThreadList = new ArrayList<CalculationThread>(); subThreadList.add(thread1); subThreadList.add(thread2); subThreadList.add(thread3); subThreadList.add(thread4); subThreadList.add(thread5); return subThreadList; } } class CalculationThread extends Thread { private List<Integer> numList; private int sum; public CalculationThread() { super(); } public CalculationThread(List<Integer> numList) { super(); this.numList = numList; } @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } for (int i : numList) { sum += i; } } public int getSum() { return sum; } public void setNumList(List<Integer> numList) { this.numList = numList; } }
Output:
Current Time Mills: 1400033660648 Current Time Mills: 1400033662639 Current Time Mills: 1400033664640 5600 // We can find out the total subCalculation time cost is: 2000ms. // So we can use this kind of technique(join method) to divide // a huge task into several sub-task and start all the sub-task at once // The main thread will wait till all the sub-task done and then gather // all the result together.
Example2: For special requirement that a list of threads run sequentially.
package edu.xmu.thread; public class SequenceThreadTest { public static void main(String[] args) throws InterruptedException { Thread sequenceThread = new Thread(new SequenceThread(), "sequenceThread"); Thread sequenceThread2 = new Thread(new SequenceThread(), "sequenceThread2"); Thread sequenceThread3 = new Thread(new SequenceThread(), "sequenceThread3"); Thread sequenceThread4 = new Thread(new SequenceThread(), "sequenceThread4"); sequenceThread.start(); sequenceThread.join(); // The caller thread(Main thread) will block until sequenceThread finished. sequenceThread2.start(); sequenceThread2.join();// The caller thread(Main thread) will block until sequenceThread2 finished. sequenceThread3.start(); sequenceThread3.join();// The caller thread(Main thread) will block until sequenceThread3 finished. sequenceThread4.start(); sequenceThread4.join();// The caller thread(Main thread) will block until sequenceThread4 finished. System.out.println("Finished"); } } class SequenceThread implements Runnable { @Override public void run() { try { Thread.sleep((long) (1000 * Math.random())); System.out .println("Thread: " + Thread.currentThread() + " is running(). Timestamp: " + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } }
Output:
Thread: Thread[sequenceThread,5,main] is running(). Timestamp: 1401247052161 Thread: Thread[sequenceThread2,5,main] is running(). Timestamp: 1401247052625 Thread: Thread[sequenceThread3,5,main] is running(). Timestamp: 1401247053363 Thread: Thread[sequenceThread4,5,main] is running(). Timestamp: 1401247054014 Finished
Another Approach:
package edu.xmu.thread; public class SequenceThreadTest { public static void main(String[] args) throws InterruptedException { Thread sequenceThread = new Thread(new SequenceThread(null), "sequenceThread"); Thread sequenceThread2 = new Thread(new SequenceThread(sequenceThread), "sequenceThread2"); Thread sequenceThread3 = new Thread( new SequenceThread(sequenceThread2), "sequenceThread3"); Thread sequenceThread4 = new Thread( new SequenceThread(sequenceThread3), "sequenceThread4"); sequenceThread.start(); System.out.println("sequenceThread started. Timestamp: " + System.currentTimeMillis()); sequenceThread2.start(); System.out.println("sequenceThread2 started. Timestamp: " + System.currentTimeMillis()); sequenceThread3.start(); System.out.println("sequenceThread3 started. Timestamp: " + System.currentTimeMillis()); sequenceThread4.start(); System.out.println("sequenceThread4 started. Timestamp: " + System.currentTimeMillis()); sequenceThread4.join(); System.out .println("Finished. Timestamp: " + System.currentTimeMillis()); } } class SequenceThread implements Runnable { Thread previousThread; public SequenceThread(Thread previousThread) { super(); this.previousThread = previousThread; } @Override public void run() { try { if (previousThread != null) { previousThread.join(); // The caller thread(current thread) will block until previousThread finished. And main thread will not blocked. } Thread.sleep((long) (1000 * Math.random())); System.out .println("Thread: " + Thread.currentThread() + " is running(). Timestamp: " + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } }
Output:
sequenceThread started. Timestamp: 1401247481556 sequenceThread2 started. Timestamp: 1401247481556 sequenceThread3 started. Timestamp: 1401247481556 sequenceThread4 started. Timestamp: 1401247481556 Thread: Thread[sequenceThread,5,main] is running(). Timestamp: 1401247482485 Thread: Thread[sequenceThread2,5,main] is running(). Timestamp: 1401247482935 Thread: Thread[sequenceThread3,5,main] is running(). Timestamp: 1401247483014 Thread: Thread[sequenceThread4,5,main] is running(). Timestamp: 1401247483916 Finished. Timestamp: 1401247483916 // We can see that MainThread will not block.