Programowanie współbieżne w języku Java
Programowanie współbieżne w języku Java
Programowanie współbieżne w języku Java
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
dr inż. Wojciech Kozioski kwiecieo 2010<br />
Materiały pomocnicze do laboratorium<br />
„<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
AiR, studia II stopnia, sem.1, piątek 14.15-16.00 GE 326<br />
Testowanie czy sprzęt jest wielordzeniowy (<strong>Java</strong> Specialists’ Newsletter 135).<br />
import java.lang.management.*;<br />
import java.util.concurrent.CountDownLatch;<br />
import java.util.concurrent.atomic.AtomicLong;<br />
public class MultiCoreTester {<br />
private static final int THREADS = 5;<br />
private static CountDownLatch ct = new CountDownLatch(THREADS);<br />
private static AtomicLong total = new AtomicLong();<br />
public static void main(String[] args)<br />
throws InterruptedException {<br />
long elapsedTime = System.nanoTime();<br />
for (int i = 0; i < THREADS; i++) {<br />
Thread thread = new Thread() {<br />
public void run() {<br />
total.addAndGet(measureThreadCpuTime());<br />
ct.countDown();<br />
}<br />
};<br />
thread.start();<br />
}<br />
ct.await();<br />
elapsedTime = System.nanoTime() - elapsedTime;<br />
System.out.println("Total elapsed time " + elapsedTime);<br />
System.out.println("Total thread CPU time " + total.get());<br />
double factor = total.get();<br />
factor /= elapsedTime;<br />
System.out.printf("Factor: %.2f%n", factor);<br />
}<br />
private static long measureThreadCpuTime() {<br />
ThreadMXBean tm = ManagementFactory.getThreadMXBean();<br />
long cpuTime = tm.getCurrentThreadCpuTime();<br />
long total=0;<br />
for (int i = 0; i < 1000 * 1000 * 1000; i++) {<br />
// keep ourselves busy for a while ...<br />
// note: we had to add some "work" into the loop or <strong>Java</strong> 6<br />
// optimizes it away. Thanks to Daniel Einspanjer for<br />
// pointing that out.<br />
total += i;<br />
total *= 10;<br />
}<br />
cpuTime = tm.getCurrentThreadCpuTime() - cpuTime;<br />
System.out.println(total + " ... " + Thread.currentThread() +<br />
": cpuTime = " + cpuTime);<br />
return cpuTime;<br />
}<br />
}<br />
Przeprowadzenie badania z poziomu systemu operacyjnego. Ze środowiska rozwojowego<br />
otrzymujemy dodatkowy narzut na wykonywane operacje. (?)<br />
Lab. „<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
1
Prosty program zawierający dwa wątki (instrukcje niskopoziomowe), działanie mechanizmu<br />
przerwao, wykorzystanie narzędzia Profiler z Netbeans IDE do obserwacji (Sun <strong>Java</strong> tutorial).<br />
public class SimpleThreads {<br />
public static long startTime = 0;<br />
// Display a message, proceed by the name of current thread.<br />
static void threadMessage (String message) {<br />
String threadName = Thread.currentThread().getName();<br />
long time = System.currentTimeMillis() - startTime;<br />
System.out.format("%s: %d: %s%n", threadName, time, message);<br />
}<br />
private static class MessageLoop implements Runnable {<br />
public void run() {<br />
String importantInfo[] = {<br />
"Message no.1", "Message no.2", "Message no.3", "Message no.4"<br />
};<br />
try {<br />
for (int i = 0; i < importantInfo.length; i++) {<br />
Thread.sleep(3500); // Pause for 3.5 seconds<br />
threadMessage(importantInfo[i]);<br />
}<br />
} catch (InterruptedException e) {<br />
threadMessage("I wasn't done!");<br />
}<br />
}<br />
}<br />
public static void main(String[] args) throws InterruptedException {<br />
// delay in miliseconds before we interrupt MessageLoop thread<br />
// default is one hour<br />
long patience = 1000*60*60;<br />
// If command line present gives patience in seconds<br />
if (args.length > 0) {<br />
try {<br />
patience = Long.parseLong(args[0]) * 1000;<br />
} catch (NumberFormatException e) {<br />
System.err.println("Argument must be an integer.");<br />
System.exit(1);<br />
}<br />
}<br />
}<br />
startTime = System.currentTimeMillis();<br />
threadMessage("Starting MessageLoop thread - patience = "+<br />
new Long(patience).toString());<br />
Thread t = new Thread(new MessageLoop(),"myThread");<br />
t.start();<br />
threadMessage("Waiting for MessageLoop thread to finish.");<br />
// loop until MessageLoop thread exits<br />
while (t.isAlive()) {<br />
threadMessage("Still waiting ...");<br />
// wait maximum 1 second for MessageLoop thread to finish<br />
t.join(1000);<br />
if (((System.currentTimeMillis() - startTime) > patience) &&<br />
t.isAlive()) {<br />
threadMessage("Tired of waiting!");<br />
t.interrupt();<br />
t.join(); //Shouldn't be long now -- wait indefinetely<br />
}<br />
}<br />
threadMessage("Finally - the end");<br />
}<br />
Lab. „<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
2
Zadanie, w którym występuje błąd współbieżności (<strong>Java</strong> Specialists’ Newsletter 155).<br />
public class BankAccount {<br />
private int balance;<br />
public BankAccount(int balance) {<br />
this.balance = balance;<br />
}<br />
public void deposit(int amount) {<br />
balance += amount;<br />
}<br />
public void withdraw(int amount) {<br />
deposit(-amount);<br />
}<br />
public int getBalance() {<br />
return balance;<br />
}<br />
}<br />
=================================================================<br />
import java.util.concurrent.*;<br />
public class BankAccountTest {<br />
public static void main(String[] args) {<br />
final BankAccount account = new BankAccount(1000);<br />
for (int i = 0; i < 2; i++) {<br />
new Thread() {<br />
{<br />
start();<br />
}<br />
}<br />
}<br />
public void run() {<br />
while (true) {<br />
account.deposit(100);<br />
account.withdraw(100);<br />
}<br />
}<br />
};<br />
}<br />
ScheduledExecutorService timer =<br />
Executors.newSingleThreadScheduledExecutor();<br />
timer.scheduleAtFixedRate(new Runnable() {<br />
public void run() {<br />
System.out.println(account.getBalance());<br />
}<br />
}, 1, 1, TimeUnit.SECONDS);<br />
Użycie opcje kompilatora języka <strong>Java</strong>:<br />
o -client hotspot<br />
o -server hotspot (znacznie silniejsza optymalizacja kodu).<br />
Wprowadzenie deklaracji volatile dla zmiennej balance z klasy BankAccount.<br />
Wprowadzenie zmiennej typu AtomicInteger. w klasie BankAccount .<br />
import java.util.concurrent.atomic.AtomicInteger;<br />
public class BankAccount {<br />
private final AtomicInteger balance =<br />
new AtomicInteger();<br />
}<br />
public BankAccount(int balance) {<br />
this.balance.set(balance);<br />
}<br />
public void deposit(int amount) {<br />
balance.addAndGet(amount);<br />
}<br />
public void withdraw(int amount) {<br />
deposit(-amount);<br />
}<br />
public int getBalance() {<br />
return balance.intValue();<br />
}<br />
Lab. „<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
3
Liczba nieaktywnych wątków możliwa do utworzenia w systemie (<strong>Java</strong> Specialists’ Newsletter 149).<br />
import java.util.concurrent.atomic.AtomicInteger;<br />
import java.util.concurrent.CountDownLatch;<br />
public class ThreadCreationTest {<br />
public static void main(String[] args)<br />
throws InterruptedException {<br />
final AtomicInteger threads_created = new AtomicInteger(0);<br />
while (true) {<br />
final CountDownLatch latch = new CountDownLatch(1);<br />
new Thread() {<br />
{ start(); }<br />
public void run() {<br />
latch.countDown();<br />
synchronized (this) {<br />
System.out.println("threads created: " +<br />
threads_created.incrementAndGet());<br />
try {<br />
wait();<br />
} catch (InterruptedException e) {<br />
Thread.currentThread().interrupt();<br />
}<br />
}<br />
}<br />
};<br />
latch.await();<br />
}<br />
}<br />
}<br />
Lab. „<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
4
Zakleszczenie (ang. Deadlock) (<strong>Java</strong> Specialists’ Newsletter 147). Aplikację należy uruchomid z<br />
poziomu systemu operacyjnego.<br />
public class BadClass extends Thread {<br />
private final Object lock1;<br />
private final Object lock2;<br />
}<br />
public BadClass(Object lock1, Object lock2) {<br />
this.lock1 = lock1;<br />
this.lock2 = lock2;<br />
}<br />
public void run() {<br />
while(true) {<br />
synchronized(lock1) {<br />
synchronized(lock2) {<br />
System.out.print('.');<br />
System.out.flush();<br />
}<br />
}<br />
}<br />
}<br />
public static void main(String[] args) {<br />
Object lock1 = new Object();<br />
Object lock2 = new Object();<br />
BadClass bc1 = new BadClass(lock1, lock2);<br />
BadClass bc2 = new BadClass(lock2, lock1);<br />
bc1.start();<br />
bc2.start();<br />
}<br />
Wyjście z zakleszczenia z generacją zrzutu:<br />
Windows: Ctrl+Break<br />
Unix: Ctrl+\ lub kill -3<br />
Analiza zrzutu – informacja o zakleszczeniu.<br />
Lab. „<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
5
Klasa Complex, która jest niezmienna (ang. immutable), stałe typu complex.<br />
package cplx;<br />
public final class Complex { // immutable class<br />
private final double re;<br />
private final double im;<br />
public static final Complex ZERO = new Complex(0, 0);<br />
public static final Complex ONE = new Complex(1, 0);<br />
public static final Complex I = new Complex(0, 1);<br />
public Complex(double re, double im) {<br />
this.re = re;<br />
this.im = im;<br />
}<br />
public double realPart() { return re; }<br />
public double imagPart() { return im; }<br />
}<br />
public Complex add(Complex c) {<br />
return new Complex(re + c.re, im + c.im);<br />
}<br />
public Complex subtract(Complex c) {<br />
return new Complex(re - c.re, im - c.im);<br />
}<br />
public Complex multiply(Complex c) {<br />
return new Complex(re * c.re - im * c.im,<br />
re * c.im + im * c.re);<br />
}<br />
public Complex divide(Complex c) {<br />
double tmp = c.re *c.re + c.im * c.im;<br />
return new Complex((re * c.re + im * c.im)/tmp,<br />
(im * c.re - re * c.im)/tmp);<br />
}<br />
@Override<br />
public boolean equals(Object o) {<br />
if (o == this) return true;<br />
if (!(o instanceof Complex)) return false;<br />
Complex c = (Complex) o;<br />
return Double.compare(re, c.re) == 0 &&<br />
Double.compare(im, c.im) == 0;<br />
}<br />
@Override<br />
public int hashCode() {<br />
int result = 17 + hashDouble(re);<br />
result = 31 * result + hashDouble(im);<br />
return result;<br />
}<br />
private static int hashDouble(double val) {<br />
long longBits = Double.doubleToLongBits(val);<br />
return (int) (longBits ^ (longBits >>> 32));<br />
}<br />
@Override<br />
public String toString() {<br />
return "(" + re + " + " + im + "i)";<br />
}<br />
Lab. „<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
6
Niezmienna (ang. immutable) klasa Complex ze statycznymi konstruktorami<br />
package cplxs;<br />
public class Complex { // immutable class with static constructors<br />
private final double re;<br />
private final double im;<br />
private Complex(double re, double im) {<br />
this.re = re;<br />
this.im = im;<br />
}<br />
public static Complex valueOf(double re, double im) {<br />
return new Complex(re, im);<br />
}<br />
public static Complex valueOfPolar(double r , double theta) {<br />
return new Complex(r * Math.cos(theta), r*Math.sin(theta));<br />
}<br />
public double realPart() { return re; }<br />
public double imagPart() { return im; }<br />
}<br />
public Complex add(Complex c) {<br />
return new Complex(re + c.re, im + c.im);<br />
}<br />
public Complex subtract(Complex c) {<br />
return new Complex(re - c.re, im - c.im);<br />
}<br />
public Complex multiply(Complex c) {<br />
return new Complex(re * c.re - im * c.im,<br />
re * c.im + im * c.re);<br />
}<br />
public Complex divide(Complex c) {<br />
double tmp = c.re *c.re + c.im * c.im;<br />
return new Complex((re * c.re + im * c.im)/tmp,<br />
(im * c.re - re * c.im)/tmp);<br />
}<br />
@Override<br />
public boolean equals(Object o) {<br />
if (o == this) return true;<br />
if (!(o instanceof Complex)) return false;<br />
Complex c = (Complex) o;<br />
return Double.compare(re, c.re) == 0 &&<br />
Double.compare(im, c.im) == 0;<br />
}<br />
@Override<br />
public int hashCode() {<br />
int result = 17 + hashDouble(re);<br />
result = 31 * result + hashDouble(im);<br />
return result;<br />
}<br />
private static int hashDouble(double val) {<br />
long longBits = Double.doubleToLongBits(val);<br />
return (int) (longBits ^ (longBits >>> 32));<br />
}<br />
@Override<br />
public String toString() {<br />
return "(" + re + " + " + im + "i)";<br />
}<br />
Lab. „<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
7
Zadanie producent – konsument rozwiązywane w czterech wersjach.<br />
Wersja 1<br />
package prodcons01;<br />
public class ProducerConsumerTest1 {<br />
public static void main(String[] args) {<br />
CubbyHole1 c = new CubbyHole1();<br />
Producer1 p1 = new Producer1(c, 1);<br />
Consumer1 c1 = new Consumer1(c, 1);<br />
p1.start();<br />
c1.start();<br />
}<br />
}<br />
=============================================<br />
package prodcons01;<br />
public class Producer1 extends Thread {<br />
private CubbyHole1 cubbyhole;<br />
private int number;<br />
public Producer1(CubbyHole1 c, int number) {<br />
cubbyhole = c;<br />
this.number = number;<br />
}<br />
@Override<br />
public void run() {<br />
for (int i = 0; i < 10; i++) {<br />
cubbyhole.put(number, i);<br />
try {<br />
sleep((int)(Math.random() * 500));<br />
} catch (InterruptedException e) {<br />
System.err.println(e.getMessage());<br />
}<br />
}<br />
}<br />
}<br />
===================================================<br />
package prodcons01;<br />
public class Consumer1 extends Thread {<br />
private CubbyHole1 cubbyhole;<br />
private int number;<br />
public Consumer1(CubbyHole1 c, int number) {<br />
cubbyhole = c;<br />
this.number = number;<br />
}<br />
@Override<br />
public void run() {<br />
int value = 0;<br />
for (int i = 0; i < 10; i++) {<br />
value = cubbyhole.get(number);<br />
try {<br />
sleep((int)(Math.random() * 1000));<br />
} catch (InterruptedException e) {<br />
System.err.println(e.getMessage());<br />
}<br />
}<br />
}<br />
}<br />
Lab. „<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
8
package prodcons01;<br />
public class CubbyHole1 {<br />
private boolean available = false;<br />
private int contents = 0;<br />
public synchronized int get(int who) {<br />
while (available == false) {<br />
try {<br />
//Wait for Producer to put value.<br />
wait();<br />
} catch (InterruptedException e) { }<br />
}<br />
available = false;<br />
System.out.format("Consumer #%d got: %d%n", who, contents);<br />
//Notify Producer that value has been retrieved.<br />
notifyAll();<br />
return contents;<br />
}<br />
}<br />
public synchronized void put(int who, int value) {<br />
while (available == true) {<br />
try {<br />
//Wait for Consumer to get value.<br />
wait();<br />
} catch (InterruptedException e) { }<br />
}<br />
contents = value;<br />
available = true;<br />
System.out.format("Producer #%d put: %d%n", who, contents);<br />
//Notify Consumer that value has been set.<br />
notifyAll();<br />
}<br />
Lab. „<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
9
Wersja 2<br />
package prodcons2;<br />
public class ProducerConsumerTest2 {<br />
public static void main(String[] args) {<br />
CubbyHole2 c = new CubbyHole2();<br />
Producer1 p1 = new Producer1(c, 1);<br />
Consumer1 c1 = new Consumer1(c, 1);<br />
p1.start();<br />
c1.start();<br />
}<br />
}<br />
==============================================<br />
package prodcons2;<br />
public class Producer1 extends Thread {<br />
private CubbyHole2 cubbyhole;<br />
private int number;<br />
public Producer1(CubbyHole2 c, int number) {<br />
cubbyhole = c;<br />
this.number = number;<br />
}<br />
@Override<br />
public void run() {<br />
for (int i = 0; i < 10; i++) {<br />
cubbyhole.put(number, i);<br />
try {<br />
sleep((int)(Math.random() * 500));<br />
} catch (InterruptedException e) {<br />
System.err.println(e.getMessage());<br />
}<br />
}<br />
}<br />
}<br />
=================================================<br />
package prodcons2;<br />
public class Consumer1 extends Thread {<br />
private CubbyHole2 cubbyhole;<br />
private int number;<br />
public Consumer1(CubbyHole2 c, int number) {<br />
cubbyhole = c;<br />
this.number = number;<br />
}<br />
@Override<br />
public void run() {<br />
int value = 0;<br />
for (int i = 0; i < 10; i++) {<br />
value = cubbyhole.get(number);<br />
try {<br />
sleep((int)(Math.random() * 1000));<br />
} catch (InterruptedException e) {<br />
System.err.println(e.getMessage());<br />
}<br />
}<br />
}<br />
}<br />
=====================================================<br />
Lab. „<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
10
package prodcons2;<br />
import java.util.concurrent.locks.Condition;<br />
import java.util.concurrent.locks.Lock;<br />
import java.util.concurrent.locks.ReentrantLock;<br />
public class CubbyHole2 {<br />
private int contents;<br />
private boolean available = false;<br />
private Lock aLock = new ReentrantLock();<br />
private Condition condVar = aLock.newCondition();<br />
public int get(int who) {<br />
aLock.lock();<br />
try {<br />
while (available == false) {<br />
try {<br />
condVar.await();<br />
} catch (InterruptedException e) { }<br />
}<br />
available = false;<br />
System.out.format("Consumer %d got: %d%n", who, contents);<br />
condVar.signalAll();<br />
} finally {<br />
aLock.unlock();<br />
}<br />
return contents;<br />
}<br />
}<br />
public void put(int who, int value) {<br />
aLock.lock();<br />
try {<br />
while (available == true) {<br />
try {<br />
condVar.await();<br />
} catch (InterruptedException e) { }<br />
}<br />
contents = value;<br />
available = true;<br />
System.out.format("Producer %d put: %d%n", who, contents);<br />
condVar.signalAll();<br />
} finally {<br />
aLock.unlock();<br />
}<br />
}<br />
Lab. „<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
11
Wersja 3<br />
package prodcons3;<br />
import java.util.concurrent.ArrayBlockingQueue;<br />
public class ProducerConsumerTest3 {<br />
public static void main(String[] args) {<br />
ArrayBlockingQueue c = new ArrayBlockingQueue(1);<br />
Producer3 p1 = new Producer3(c, 1);<br />
Consumer3 c1 = new Consumer3(c, 1);<br />
p1.start();<br />
c1.start();<br />
}<br />
}<br />
======================================================<br />
package prodcons3;<br />
import java.util.concurrent.BlockingQueue;<br />
public class Producer3 extends Thread {<br />
private BlockingQueue cubbyhole;<br />
private int number;<br />
public Producer3(BlockingQueue c, int num) {<br />
cubbyhole = c;<br />
number = num;<br />
}<br />
public void run() {<br />
for (int i = 0; i < 10; i++) {<br />
try {<br />
cubbyhole.put(i);<br />
System.out.format("Producer #%d put: %d%n", number, i);<br />
sleep((int)(Math.random() * 500));<br />
} catch (InterruptedException e) { }<br />
}<br />
}<br />
}<br />
===========================================================<br />
package prodcons3;<br />
import java.util.concurrent.BlockingQueue;<br />
public class Consumer3 extends Thread {<br />
private BlockingQueue cubbyhole;<br />
private int number;<br />
public Consumer3(BlockingQueue c, int num) {<br />
cubbyhole = c;<br />
number = num;<br />
}<br />
}<br />
public void run() {<br />
int value = 0;<br />
for (int i = 0; i < 10; i++) {<br />
try {<br />
value = cubbyhole.take();<br />
System.out.format("Consumer #%d got: %d%n", number, value);<br />
} catch (InterruptedException e) { }<br />
}<br />
}<br />
Lab. „<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
12
Wersja 4<br />
package prodcons04;<br />
public class ProducerConsumerTest4 {<br />
public static void main(String[] args) {<br />
SemaphoreBoundedBuffer c = new SemaphoreBoundedBuffer(1);<br />
Producer4 p1 = new Producer4(c, 1);<br />
Consumer4 c1 = new Consumer4(c, 1);<br />
p1.start();<br />
c1.start();<br />
}<br />
}<br />
==============================================================<br />
package prodcons04;<br />
public class Producer4 extends Thread {<br />
private SemaphoreBoundedBuffer cubbyhole;<br />
private int number;<br />
public Producer4(SemaphoreBoundedBuffer c, int number) {<br />
cubbyhole = c;<br />
this.number = number;<br />
}<br />
@Override<br />
public void run() {<br />
for (int i = 0; i < 10; i++) {<br />
try {<br />
cubbyhole.put(number, i);<br />
sleep((int)(Math.random() * 500));<br />
} catch (InterruptedException e) {<br />
System.err.println(e.getMessage());<br />
}<br />
}<br />
}<br />
}<br />
================================================================<br />
package prodcons04;<br />
public class Consumer4 extends Thread {<br />
private SemaphoreBoundedBuffer cubbyhole;<br />
private int number;<br />
public Consumer4(SemaphoreBoundedBuffer c, int number) {<br />
cubbyhole = c;<br />
this.number = number;<br />
}<br />
@Override<br />
public void run() {<br />
int value = 0;<br />
for (int i = 0; i < 10; i++) {<br />
try {<br />
value = (Integer)(cubbyhole.take(number));<br />
sleep((int)(Math.random() * 1000));<br />
} catch (InterruptedException e) {<br />
System.err.println(e.getMessage());<br />
}<br />
}<br />
}<br />
}<br />
==================================================================<br />
Lab. „<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
13
package prodcons04;<br />
import java.util.concurrent.Semaphore;<br />
public class SemaphoreBoundedBuffer {<br />
private final Semaphore availableItems, availableSpaces;<br />
private final E[] items;<br />
private int putPosition = 0, takePosition = 0;<br />
public SemaphoreBoundedBuffer(int capacity) {<br />
if (capacity
Szkielety interfejsy Egzekutor do zarządzania wątkami, interfejs Callable oraz klasa Future<br />
FixedThreadPoolExcecutor<br />
package thp01;<br />
import java.util.concurrent.ExecutorService;<br />
import java.util.concurrent.Executors;<br />
public class ThreadPoolTest {<br />
public static void main(String[] args) {<br />
int numWorkers = Integer.parseInt(args[0]);<br />
int threadPoolSize = Integer.parseInt(args[1]);<br />
ExecutorService tpes = Executors.newFixedThreadPool(threadPoolSize);<br />
WorkerThread[] workers = new WorkerThread[numWorkers];<br />
for (int i = 0; i < numWorkers; i++) {<br />
workers[i] = new WorkerThread(i);<br />
tpes.execute(workers[i]);<br />
}<br />
tpes.shutdown();<br />
}<br />
}<br />
======================================================================<br />
package thp01;<br />
public class WorkerThread implements Runnable {<br />
private int workerNumber;<br />
WorkerThread (int number) {<br />
workerNumber = number;<br />
}<br />
}<br />
public void run(){<br />
for (int i = 0; i
Cached Executor oraz zadanie typu Callable.<br />
package thp02;<br />
import java.util.concurrent.ExecutorService;<br />
import java.util.concurrent.Executors;<br />
import java.util.concurrent.Future;<br />
public class ThreadPoolTest {<br />
public static void main(String[] args) {<br />
int numWorkers = Integer.parseInt(args[0]);<br />
ExecutorService tpes = Executors.newCachedThreadPool();<br />
CallableWorkerThread[] workers = new<br />
CallableWorkerThread[numWorkers];<br />
Future futures[] = new Future[numWorkers];<br />
for (int i = 0; i < numWorkers; i++) {<br />
workers[i] = new CallableWorkerThread(i);<br />
futures[i] = tpes.submit(workers[i]);<br />
}<br />
for (int i = 0; i < numWorkers; i++) {<br />
try {<br />
System.out.format("Ending worker: %d%n", futures[i].get());<br />
} catch (Exception e) {<br />
System.err.println(e.getMessage());<br />
}<br />
}<br />
tpes.shutdown();<br />
}<br />
}<br />
=========================================================================<br />
package thp02;<br />
import java.util.concurrent.Callable;<br />
public class CallableWorkerThread implements Callable{<br />
private int workerNumber;<br />
CallableWorkerThread (int number) {<br />
workerNumber = number;<br />
}<br />
}<br />
public Integer call(){<br />
for (int i = 0; i
Mnożenie macierzy – trzy wersje (książkowa – naiwna, z biblioteki Jama, wielowątkowa).<br />
package mmold;<br />
import java.util.concurrent.ExecutorService;<br />
import java.util.concurrent.Executors;<br />
import java.util.concurrent.TimeUnit;<br />
public class MatrixMultiply02 {<br />
public static void main(String[] args) {<br />
int m = 6;<br />
int n = 7;<br />
int k = 8;<br />
double[][] a = new double[m][n];<br />
double[][] b = new double[n][k];<br />
double[][] c = new double[m][k];<br />
for (int i = 0; i < m; ++i) {<br />
for (int j = 0; j < n; ++j) {<br />
a[i][j] = 1.0D;<br />
}<br />
}<br />
for (int i = 0; i < n; ++i) {<br />
for (int j = 0; j < k; ++j) {<br />
b[i][j] = 1.0D;<br />
}<br />
}<br />
System.out.println("=== First (naive method) test ===");<br />
printMatrix(a, m, n, "A");<br />
printMatrix(b, n, k, "B");<br />
naiveMatrixMultiply(a, b, c);<br />
printMatrix(c, m, k, "C");<br />
System.out.println("=== Second (jama method) test ===");<br />
printMatrix(a, m, n, "A");<br />
printMatrix(b, n, k, "B");<br />
jamaMatrixMultiply(a, b, c);<br />
printMatrix(c, m, k, "C");<br />
}<br />
System.out.println("=== Third (threaded - Executors) test ===");<br />
printMatrix(a, m, n, "A");<br />
printMatrix(b, n, k, "B");<br />
threadedMatrixMultiply(a, b, c, 2);<br />
printMatrix(c, m, k, "C");<br />
// book like method matrix multiplication - matrix indexing is very slow<br />
static void naiveMatrixMultiply(final double[][] a, final double[][] b,<br />
final double[][] c) {<br />
// check(a,b,c); // checks for null args, incorrectly sized matrices,<br />
etc.<br />
final int m = a.length;<br />
final int n = b.length;<br />
final int p = b[0].length;<br />
for (int j = 0; j < p; j++) {<br />
for (int i = 0; i < m; i++) {<br />
double s = 0;<br />
for (int k = 0; k < n; k++) {<br />
s += a[i][k] * b[k][j];<br />
}<br />
c[i][j] = s;<br />
}<br />
}<br />
}<br />
// Jama multiplication - much faster vector indexing than double array<br />
indexing<br />
static void jamaMatrixMultiply(final double[][] a, final double[][] b,<br />
Lab. „<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
17
final double[][] c) {<br />
// check(a,b,c);<br />
final int m = a.length;<br />
final int n = b.length;<br />
final int p = b[0].length;<br />
}<br />
final double[] Bcolj = new double[n];<br />
for (int j = 0; j < p; j++) {<br />
for (int k = 0; k < n; k++) {<br />
Bcolj[k] = b[k][j];<br />
}<br />
for (int i = 0; i < m; i++) {<br />
final double[] Arowi = a[i];<br />
double s = 0;<br />
for (int k = 0; k < n; k++) {<br />
s += Arowi[k] * Bcolj[k];<br />
}<br />
c[i][j] = s;<br />
}<br />
}<br />
// Jama type method which uses several threads<br />
static void threadedMatrixMultiply(final double[][] a, final double[][] b,<br />
final double[][] c, final int numTasks) {<br />
// check(a,b,c);<br />
final int m = a.length;<br />
final int n = b.length;<br />
final int p = b[0].length;<br />
final ExecutorService executor = Executors.newFixedThreadPool(numTasks);<br />
for (int interval = numTasks, end = p, size = (int) Math.ceil(p * 1.0 /<br />
numTasks);<br />
interval > 0; interval--, end -= size) {<br />
final int to = end;<br />
final int from = Math.max(0, end - size);<br />
final Runnable runnable = new Runnable() {<br />
public void run() {<br />
final double[] Bcolj = new double[n];<br />
for (int j = from; j < to; j++) {<br />
for (int k = 0; k < n; k++) {<br />
Bcolj[k] = b[k][j];<br />
}<br />
for (int i = 0; i < m; i++) {<br />
final double[] Arowi = a[i];<br />
double s = 0;<br />
for (int k = 0; k < n; k++) {<br />
s += Arowi[k] * Bcolj[k];<br />
}<br />
c[i][j] = s;<br />
}<br />
}<br />
}<br />
};<br />
executor.execute(runnable);<br />
}<br />
try {<br />
executor.shutdown();<br />
executor.awaitTermination(2, TimeUnit.DAYS); // O(n^3) can take a<br />
while!<br />
} catch (final InterruptedException e) {<br />
System.out.println("Interrupted.");<br />
// empty(c);<br />
}<br />
}<br />
public static void printMatrix(double[][] A, int aRow, int aCol, String<br />
str) {<br />
System.out.println("Matrix " + str + " nRows = " + aRow + " nCols = " +<br />
aCol);<br />
Lab. „<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
18
}<br />
}<br />
for (int i = 0; i < aRow; i++) {<br />
for (int j = 0; j < aCol; j++) {<br />
System.out.print(A[i][j] + " ");<br />
}<br />
System.out.println();<br />
}<br />
System.out.println();<br />
Lab. „<strong>Programowanie</strong> <strong>współbieżne</strong> w <strong>języku</strong> <strong>Java</strong>”<br />
19