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

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

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!