07.03.2014 Views

Programowanie współbieżne w języku Java

Programowanie współbieżne w języku Java

Programowanie współbieżne w języku Java

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!