欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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.

 

相关标签: Thead Sleep Join