Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ganesh_JavaSE7_Programming_1z0-804_study_guide.pdf
Скачиваний:
94
Добавлен:
02.02.2015
Размер:
5.88 Mб
Скачать

Chapter 14 Concurrency

Spawning thread for summing in range 400001 to 500000 Spawning thread for summing in range 500001 to 600000 Spawning thread for summing in range 600001 to 700000 Spawning thread for summing in range 700001 to 800000 Spawning thread for summing in range 800001 to 900000 Spawning thread for summing in range 900001 to 1000000

Sum by threads = 500000500000, sum using formula = 500000500000

Let’s now analyze how this program works. In this program, you need to find the sum of 1..N where N is one million (a large number). The class SumCalc implements Callable<Long> to sum the values in the range from to to. The call() method performs the actual computation of the sum by looping from from to to and returns the intermediate sum value as a Long value.

In this program, you divide the summation task among multiple threads. You can determine the number of threads based on the number of cores available in your processor; however, for the sake of keeping the program simpler, use ten threads.

In the main() method, you create a ThreadPool with ten threads. You are going to create ten summation tasks, so you need a container to hold the references to those tasks. Use ArrayList to hold the Future<Long> references.

In the first for loop in main(), you create ten tasks and submit them to the ExecutorService. As you submit a task, you get a Future<Long> reference and you add it to the ArrayList.

Once you’ve created the ten tasks, you traverse the array list in the next for loop to get the results of the tasks. You sum up the partial results of the individual tasks to compute the final sum.

Once you get the computed sum of values from one to one million, you use the simple formula N * (N + 1)/2 to find the formula sum. From the output, you can see that the computed sum and the formula sum are equal, so you can ascertain that your logic of dividing the tasks and combining the results of the tasks worked correctly.

Now, before we move on to discuss the fork/join framework, we’ll quickly discuss a few classes that are useful for concurrent programming.

ThreadFactory

ThreadFactory is an interface that is meant for creating threads instead of explicitly creating threads by calling new Thread(). For example, assume that you often create high-priority threads. You can create a MaxPriorityThreadFactory to set the default priority of threads created by that factory to maximum priority (see Listing 14-15).

Listing 14-15.  TestThreadFactory.java

import java.util.concurrent.*;

//A ThreadFactory implementation that sets the thread priority to max

//for all the threads it creates

class MaxPriorityThreadFactory implements ThreadFactory { private static long count = 0;

public Thread newThread(Runnable r) { Thread temp = new Thread(r);

temp.setName("prioritythread" + count++); temp.setPriority(Thread.MAX_PRIORITY); return temp;

}

}

468

Chapter 14 Concurrency

class ARunnable implements Runnable { public void run() {

System.out.println("Running the created thread ");

}

}

class TestThreadFactory {

public static void main(String []args) {

ThreadFactory threadFactory = new MaxPriorityThreadFactory(); Thread t1 = threadFactory.newThread(new ARunnable()); System.out.println("The name of the thread is " + t1.getName());

System.out.println("The priority of the thread is " + t1.getPriority()); t1.start();

}

}

It prints the following:

The name of the thread is prioritythread0 The priority of the thread is 10

Running the created thread

With the use of ThreadFactory, you can reduce boilerplate code to set thread priority, name, thread-pool, etc.

The ThreadLocalRandom Class

When you do concurrent programming, you’ll find that there is often a need to generate random numbers. Using Math.random() is not efficient for concurrent programming. For this reason, the java.util.concurrent package introduces the ThreadLocalRandom class, which is suitable for use in concurrent programs. You can use

ThreadLocalRandom.current() and then call methods such as nextInt() and nextFloat() to generate the random numbers.

TimeUnit Enumeration

You’ve already seen some methods earlier in this chapter that take TimeUnit as an argument. TimeUnit is an enumeration that is used to specify the resolution of the timing. The unit of time in TimeUnit can be one of DAYS,

HOURS, MINUTES, SECONDS, MICROSECONDS, MILLISECONDS, or NANOSECONDS. The enumeration also has useful methods for converting between these time units. For example,

System.out.printf("One day has %d hours, %d minutes, %d seconds", TimeUnit.DAYS.toHours(1), TimeUnit.DAYS.toMinutes(1), TimeUnit.DAYS.toSeconds(1));

prints

One day has 24 hours, 1440 minutes, 86400 seconds

Some of the methods in the Java API use specific periods. For example, the sleep() method takes time to sleep in milliseconds. So, what if you want to specify the time for thread sleep in some other time unit, say seconds or days? TimeUnit makes this task easy. See Listing 14-16 for an example.

469

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]