Java Programowanie Obiektowe Mateusz Cicheński
Wielowątkowość Proces a wątek? Thread vs Runnable sleep(), interrupt(), join() Problemy wielowątkowości Obiekty niemodyfikowalne (immutable) Serializacja Przydatne odnośniki Plan zajęć
Proces często traktowany jako wystąpienie uruchomionego programu, posiada przydzielony zbiór zasobów (pamięć, pliki etc.) Wątek lekki proces, wykonuje część programu w sposób współbieżny w obrębie procesu, korzysta z zasobów procesu (zasoby te są współdzielone)
public class HelloWorldThread extends Thread { @Override public void run() { System.out.println("Hello world from Thread"); public class HelloWorldRunnable implements Runnable { @Override public void run() { System.out.println("Hello world from Runnable"); Thread vs Runnable
public static void main(string[] args) { new Thread(new HelloWorldRunnable()).start(); new HelloWorldThread().start(); Hello world from Runnable Hello world from Thread Thread vs Runnable c.d.
public class HelloWorldThread extends Thread { @Override public void run() { try { sleep(5000); catch (InterruptedException e) { wykonywanie wątku jest wstrzymane na określony czas, umożliwiając innym wątkom na wykorzystanie czasu procesora (ale uśpiony wątek nadal może być przerwany!) sleep()
public class HelloWorldThread extends Thread { @Override public void run() { while (true); public static void main(string[] args) throws InterruptedException { Thread thread = new HelloWorldThread(); thread.start; thread.interrupt(); System.out.println(thread.isInterrupted()); //prints true interrupt() zły przykład
public class HelloWorldThread extends Thread { @Override public void run() { while (true) { heavycalculus(); if (Thread.interrupted()) return; public static void main(string[] args) throws InterruptedException { Thread thread = new HelloWorldThread(); thread.start(); thread.interrupt(); interrupt() lepszy przykład
public class HelloWorldThread extends Thread { @Override public void run() { while (true) { heavycalculus(); if (Thread.interrupted()) throw new InterruptedException(); public static void main(string[] args) throws InterruptedException { Thread thread = new HelloWorldThread(); thread.start(); thread.interrupt(); interrupt() jeszcze lepiej
public class HelloWorldThread extends Thread { @Override public void run() { try { sleep(5000); catch (InterruptedException e) { public static void main(string[] args) throws InterruptedException { Thread thread = new HelloWorldThread(); thread.start(); thread.join(); System.out.println( Thread died ); join()
Deadlock Zagłodzenie, livelock Nakładanie się wątków Niespójny stan pamięci Problemy wielowątkowości
Zgodnie z dobrymi manierami kiedy kłaniam się przyjacielowi powinienem pozostać w skłonie dopóty, dopóki przyjaciel ów nie będzie miał okazji do odwdzięczenia się ukłonem. Deadlock
Problem pięciu filozofów Jeśli dwa widelce są równocześnie wolne złap je równocześnie, zjedz i odłóż Zagłodzenie
Dwa wątki chcąc uniknąć deadlock a wzajemnie sobie ustępują, co prowadzi do tego, że żaden z nich nie może kontynuować obliczeń Livelock
public class NamedNumber { private int number; private String name; public NamedNumber(int number, String name) { this.number = number; this.name = name; public void set(int number, String name) { synchronized (this) { this.number = number; this.name = name; public synchronized int getnumber() { return number; NamedNumber number = new NamedNumber(42, "fourty two");... int mynumber = number.getnumber(); //another thread: number.set(0, "nil") String mynumbername = number.getname(); //mynumber = 42, mynumbername = "nil" synchronized (number) { int myint = number.getnumber(); String myname = number.getname(); public synchronized String getname() { return name; public synchronized void changesign() { if (number > 0) { name = "minus " + name; else if (number < 0) { name = name.substring(6); number = -number; Nakładanie się wątków
final public class ImmutableNamedNumber { final private int number; final private String name; public ImmutableNamedNumber(int number, String name) { this.number = number; this.name = name; public int getnumber() { return number; public String getname() { return name; public ImmutableNamedNumber changesign() { if (number > 0) { return new ImmutableNamedNumber(-number, "minus " + name); else if (number < 0) { return new ImmutableNamedNumber(-number, name.substring(6)); return this; //zero is not changed Obiekty typu immutable
Lock więcej możliwości niż synchronizowanie kodu Executor wysokopoziomowe API do zarządzania wątkami Kolekcje wielowątkowe (thread-safe) BlockingQueue, ConcurrentMap Zmienne atomowe (np. AtomicInteger) Inne przydatne elementy dla wielowątkowych aplikacji w Javie
import java.io.serializable; public class LuckyNumber implements Serializable { private static final long serialversionuid = -2531937043590753438L; public final static String message = "Your lucky number is %s! (and obviously not %s)"; public int number; public transient int notluckynumber; public LuckyNumber(int number) { this.number = number; this.notluckynumber = number; public String getmessage() { return String.format(message, number, notluckynumber); Serializacja
public static void serialize(object object, String filename) { try { FileOutputStream fileout = new FileOutputStream(filename); ObjectOutputStream out = new ObjectOutputStream(fileOut); out.writeobject(object); out.close(); fileout.close(); catch (IOException i) { i.printstacktrace(); public static LuckyNumber deserialize(string filename) { LuckyNumber number = null; try { FileInputStream filein = new FileInputStream(filename); ObjectInputStream in = new ObjectInputStream(fileIn); number = (LuckyNumber) in.readobject(); in.close(); filein.close(); catch (IOException i) { i.printstacktrace(); catch (ClassNotFoundException c) { c.printstacktrace(); return number; Serializacja c.d.
public static void main(string[] args) { String filename = "myluckynumber.ser"; LuckyNumber number = new LuckyNumber(42); serialize(number, filename); public static void main(string[] args) { String filename = "myluckynumber.ser"; LuckyNumber number = deserialize(filename); System.out.println(number.getMessage()); Your lucky number is 42! (and obviously not 0) Serializacja c.d.
import java.io.serializable; public class LuckyNumber implements Serializable { private static final long serialversionuid = -210178459216854737L; //this is not serialized by default! public static String message = "Your lucky number is %s! (and obviously not %s)"; public int number; public transient int notluckynumber; public LuckyNumber(int number) { this.number = number; this.notluckynumber = number; public String getmessage() { return String.format(message, number, notluckynumber); private void writeobject(objectoutputstream oos) throws IOException { oos.defaultwriteobject(); oos.writeutf(message); private void readobject(objectinputstream ois) throws ClassNotFoundException, IOException { ois.defaultreadobject(); message = ois.readutf(); Serializacja c.d. 2
public static void main(string[] args) { String filename = "mypirateluckynumber.ser"; LuckyNumber.message = "Your blastedly lucky number be %s! (and obviosly nay %s)"; LuckyNumber number = new LuckyNumber(42); serialize(number, filename); public static void main(string[] args) { String filename = "mypirateluckynumber.ser"; LuckyNumber number = null; number = deserialize(filename); System.out.println(number.getMessage()); Your blastedly lucky number be 42! (and obviosly nay 0) Serializacja c.d. 2
http://sourceforge.net/projects/javaconcu rrenta/ http://docs.oracle.com/javase/8/docs/api/ java/io/serializable.html Odnośniki
Pytania? http://bit.ly/oop2015