Многопоточность в Java. Понятие потока Поток – это одна из веточек вычислительного процесса. Каждый поток выполняет свои действия в пределах одного приложения.

Презентация:



Advertisements
Похожие презентации
Параллельная работа сокетов в C#. Потоки в C# using System; using System.Threading; public class ThreadExample { public static void ThreadProc() { for.
Advertisements

Test 9 Вопрос 1. public class A { private String runNow() { return "High"; } static class B extends A { public String runNow() { return "Low"; } } public.
Test 5 Вопрос 1. В результате компиляции каких строк будет происходить ошибка компиляции: public class Main { public static void main(String[] args) {
Test 14 Вопрос 1. class Main { public void method() { static class One { public One() { System.out.println("From one"); } } public static void main(String...
Test 11 Вопрос 1. class HashTest { private static Set set = new LinkedHashSet (); public static void main(String[] args) { set.add("one"); set.add("two");
Test21 Вопрос 1. public class Test { void a1(Object... i){ System.out.println("[Object... i]"); } void a1(Integer... i){ System.out.println("[Integer...
Test 16 Вопрос 1. class Clazz { { System.out.println("non-static init"); } public static void main(String a[]) { System.out.println("main"); Clazz ob1.
Test 8 Вопрос 1. class Class1 { Class1(int i) { System.out.println("Class1(int)"); } public class Class2 extends Class1 { Class2(double d) { // 1 this((int)
Test 17 Вопрос 1. public class TKO { public static void main(String[] args) { String s = "-"; Integer x = 343; long L343 = 343L; if (x.equals(L343)) s.
Интерфейсы в Java. Интерфейсы Множественное наследование не допускается при помощи классов Допускается множественное наследование при помощи интерфейсов.
Test 10 Вопрос 1. public class Test implements Iterator { // 1 private List list = new ArrayList (); // 2 public void addList(T... ts) { Collections.addAll(list,
Test 3 Вопрос 1. 01:package test; 02: public class Test { 03: public static void main(String [] args) { 04: Test test = new Test(); 05: System.out.println(test.toString());}
Test 13 Вопрос 1. public class StringTest { public static void main(String[] arg){ test(new String[] { null });} static void test(Object[] o){System.out.print(1);}
Test 12 Вопрос 1. public class Cast { public static void main (String[] args){ byte b = 128; int i = b; System.out.println(i); } } a)Во время выполнения.
МНОГОПОТОЧНОЕ ПРОГРАММИРОВАНИЕ В JAVA Пакеты java.lang java.util.concurrent.
Синтаксис языка Java. Символы и синтаксис Перевод строчки эквивалентен пробелу Регистр в именах различается.
Test15 Вопрос 1. class AClass { } public class Test { public static void main (String... args) { ArrayList a = new ArrayList (); AClass aaaClass = new.
Практическое программирование на Java к.ф.-м.н. Козлов Дмитрий Дмитриевич Кафедра АСВК, Лаборатория Вычислительных комплексов.
Модель приложений.NET. Среда платформы Win32, в которой выполняется программа, называется ее процессом. Эта среда состоит из: адресного пространства,
Многопоточное программирование на Java Java Advanced.
Транксрипт:

Многопоточность в Java

Понятие потока Поток – это одна из веточек вычислительного процесса. Каждый поток выполняет свои действия в пределах одного приложения

Причины запуска нескольких потоков Некоторые задачи не могут выполняться без потоков. Некоторые задачи могут работать в фоновом режиме, позволяя пользователю параллельно выполнять другие действия. Некоторые задачи многопоточны изначально. Например, видео со звуком требует одного потока для вывода видео, а другого – для вывода звука. Некоторые игровые программы пытаются отражать реальный мир, выполняя сразу несколько действий в одно и то же время. Некоторые объемные задачи могут разделяться на несколько частей, которые выполняются параллельно. В системах с одним центральным процессором многопоточность обеспечивается путем применения процедуры квантования времени (time-slicing).

import java.util.Timer; import java.util.TimerTask; /** Простой пример поточности */ public class Reminder { Timer timer; public Reminder(int seconds) { timer = new Timer(); timer.schedule(new RemindTask(), seconds*1000); } class RemindTask extends TimerTask { public void run() { System.out.println("Time's up!"); timer.cancel(); //Terminate the timer thread } public static void main(String args[]) { System.out.println("About to schedule task."); new Reminder(5); new Reminder(10); System.out.println("Task scheduled."); } About to schedule task. Task scheduled. Time's up!

import java.util.TimerTask; import java.awt.Toolkit; import java.util.Timer; public class ReminderBeep { Toolkit toolkit; Timer timer; public ReminderBeep(int seconds) { toolkit = Toolkit.getDefaultToolkit(); timer = new Timer(); timer.schedule(new RemindTask(), seconds*1000); } class RemindTask extends TimerTask { public void run() { System.out.println("Time's up!"); toolkit.beep(); System.exit(0); //Stops the AWT thread } public static void main(String args[]) { System.out.println("About to schedule task."); new ReminderBeep(5); System.out.println("Task scheduled."); } Будильник

Создание потоков Наследование от класс Thread public class MyThread extends Thread { public void run() { // некоторое долгое действие, выполняемое потоке } Запуск потока MyThread t = new MyThread(); t.start(); Реализация интерфейса Runnable public class MyRunnable implements Runnable { public void run() { // некоторое долгое действие, выполняемое в потоке } Запуск потока Runnable r = new MyRunnable(); Thread t = new Thread(r); t.start();

Поток наследует от Thread public class ThreadTest extends Thread { public void run() { double calc; for (int i=0; i

Поток наследует от Runnable public class ThreadTest implements Runnable { public void run() { double calc; for (int i=0; i

import java.awt.Graphics; import java.util.*; import java.text.DateFormat; import java.applet.Applet; public class Clock extends Applet implements Runnable { private Thread clockThread = null; public void start() { if (clockThread == null) { clockThread = new Thread(this, "Clock"); clockThread.start(); } public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { repaint(); try { Thread.sleep(1000); } catch (InterruptedException e){ } public void paint(Graphics g) { // get the time and convert it to a date Calendar cal = Calendar.getInstance(); Date date = cal.getTime(); // format it and display it DateFormat dateFormatter = DateFormat.getTimeInstance(); g.drawString(dateFormatter.format(date), 5, 10); } // overrides Applet's stop method, not Thread's public void stop() { clockThread = null; } Часики

Приоритеты потоков MAX_PRIORITY (10) NORM_PRIORITY (5) MIN_PRIORITY (1) setPriority(int); int getPriority();

Приоритеты потоков public static void main(String s[]) { // Подготовка потоков Thread t[] = new Thread[3]; for (int i=0; i

Жизненный цикл потока yield – приводит к переключению контекста с текущего на следующий доступный подпроцесс sleep - блокирует текущий подпроцесс на n миллисекунд wait- текущий подпроцесс отдает управление и переходит в режим ожидания - до тех пор пока другой подпроцесс не вызовет метод notify с тем же объектом. Состояния потока: NEW – создан, но не запущен; RUNNABLE – работает; BLOCKED – блокирован; WAITING – ожидает конец работы другого потока; TIMED_WATING – ждет некоторое время; TERMINATED – окончен.

Основной поток Thread t = Thread.currentThread(); join(); boolean isAlive(); public class RunnableThread implements Runnable { Thread t; public RunnableThread(String str) { t = new Thread(this,str); } public void run() { for (int i = 0; i < 5; i++) { System.out.println(i + " " + t.getName()); try { Thread.sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) {} } System.out.println("DONE! " + t.getName()); } public static void main(String[] args) { RunnableThread [] p = new RunnableThread[3]; for ( int i = 0; i < 3; i++) { p[i] = new RunnableThread("Thread "+i); p[i].t.start(); try{ p[i].t.join(); }catch(InterruptedException e){} } System.out.println( "Finished"); } 0 Thread 0 1 Thread 0 2 Thread 0 3 Thread 0 4 Thread 0 DONE! Thread 0 0 Thread 1 1 Thread 1 2 Thread 1 3 Thread 1 4 Thread 1 DONE! Thread 1 0 Thread 2 1 Thread 2 2 Thread 2 3 Thread 2 4 Thread 2 DONE! Thread 2 Finished

Прерывание потока public class TestInterrupt extends Thread { public TestInterrupt() { } public void run() { try { for ( int i=0; i

Остановка потока public class TestStop extends Thread { private volatile boolean stopping; private Thread secondThread; public TestStop() { } public void run() { secondThread = Thread.currentThread(); stopping = false; int counter = 0; while( !stopping) { System.out.println("counter = " + counter); counter++; try { Thread.sleep(1000); }catch (InterruptedException ie) { System.out.println("Sleep interrupted in run()"); } } } public void stopIt() { this.stopping = true; } public static void main(String[] args) { TestStop t = new TestStop(); t.start(); //Delay for a few seconds to let the other thread get going try { Thread.sleep(2500); }catch (InterruptedException ie) { System.out.println("Sleep interrupted in main()"); } System.out.println("About to stop the other thread"); t.stopIt(); System.out.println("Exiting from Main"); } } counter = 0 counter = 1 counter = 2 About to stop the other thread Exiting from Main может изменяться вне данного потока

Демон-потоки Демон-потоки позволяют описывать фоновые процессы, которые нужны только для обслуживания основных потоков выполнения и не могут существовать без них. Для работы с этим свойством существуют методы setDaemon() и isDaemon(). public class ThreadTest implements Runnable { // Группа, в которой будут находиться все потоки public final static ThreadGroup GROUP = new ThreadGroup("Daemon demo"); // Значение, указывается при создании объекта private int start; public ThreadTest(int s) { start = (s%2==0)? s: s+1; //проверка на четность new Thread(GROUP, this, "Thread "+ start).start(); } public void run() { // Начинаем обратный отсчет for (int i=start; i>0; i--) { try { Thread.sleep(300); } catch (InterruptedException e) {} if (start>2 && i==start/2) { new ThreadTest(i); } public static void main(String s[]) { new ThreadTest(8); new DaemonDemo(); } class DaemonDemo extends Thread { public DaemonDemo() { super("Daemon demo thread"); setDaemon(true); start(); } public void run() { Thread threads[]=new Thread[10]; while (true) { // Получаем набор всех потоков из группы int count = ThreadTest.GROUP.activeCount(); if (threads.length

Синхронизация import java.lang.InterruptedException; class Callme { void call(String msg) { System.out.println("["+msg); try { Thread.sleep(1000); }catch(InterruptedException e) { System.out.println("Прерывание"); } System.out.println("]"); } class Caller implements Runnable { String msg; Callme target; Thread t; public Caller(Callme targ, String s) { target=targ; msg = s; t = new Thread(this); t.start(); } public void run() { target.call(msg); } } class Test { public static void main(String args[]) { Callme target = new Callme(); Caller obj1 = new Caller(target, "Привет"); Caller obj2 = new Caller(target,"Синхронизированный"); Caller obj3 = new Caller(target, "Мир"); try { obj1.t.join(); obj2.t.join(); obj3.t.join(); }catch(InterruptedException e) { System.out.println("Прерывание"); } [Привет [Синхронизированный [Мир ]

Монитор Монитор – это механизм управления связью между процессами. Как только поток входит в монитор, все другие потоки должны ждать, пока он не выйдет из монитора. Служит для защиты разделяемого ресурса.

Синхронизация потоков import java.lang.InterruptedException; class Callme { void call(String msg) { System.out.println("["+msg); try { Thread.sleep(1000); }catch(InterruptedException e) { System.out.println("Прерывание"); } System.out.println("]"); } class Caller implements Runnable { String msg; Callme target; Thread t; public Caller(Callme targ, String s) { target=targ; msg = s; t = new Thread(this); t.start(); } public void run() { synchronized(target) { target.call(msg); } } class Test { public static void main(String args[]) { Callme target = new Callme(); Caller obj1 = new Caller(target, "Привет"); Caller obj2 = new Caller(target,"Синхронизированный"); Caller obj3 = new Caller(target, "Мир"); try { obj1.t.join(); obj2.t.join(); obj3.t.join(); }catch(InterruptedException e) { System.out.println("Прерывание"); } [Привет ] [Мир ] [Синхронизированный ]

Синхронизация потоков import java.lang.InterruptedException; class Callme { synchronized void call(String msg) { System.out.println("["+msg); try { Thread.sleep(1000); }catch(InterruptedException e) { System.out.println("Прерывание"); } System.out.println("]"); } class Caller implements Runnable { String msg; Callme target; Thread t; public Caller(Callme targ, String s) { target=targ; msg = s; t = new Thread(this); t.start(); } public void run() { target.call(msg); } } class Test { public static void main(String args[]) { Callme target = new Callme(); Caller obj1 = new Caller(target, "Привет"); Caller obj2 = new Caller(target,"Синхронизированный"); Caller obj3 = new Caller(target, "Мир"); try { obj1.t.join(); obj2.t.join(); obj3.t.join(); }catch(InterruptedException e) { System.out.println("Прерывание"); } [Привет ] [Мир ] [Синхронизированный ]

Object void wait()wait сообщает вызывающему потоку, что нужно уступить монитор и переходит в режим ожидания («спячки»), пока некоторый другой поток не введет тот же монитор и не вызовет notify() void notify()notify «пробуждает» первый поток (который вызвал wait() ) на том же самом объекте void notifyAll()notifyAll «пробуждает» все потоки, которые вызвали wait() на том же самом объекте void wait(long timeout)wait то же, но указано время ожидания в милисекундах void wait(long timeout, int nanos)wait то же, но указано время ожидания в милисекундах и наносекундах

Межпоточные связи class Q { int n; synchronized int get() { System.out.println("Got: " + n); return n; } synchronized void put(int n) { this.n = n; System.out. println("Put: " + n); } } class Producer implements Runnable { Q q; Producer(Q q) { this.q = q; new Thread(this,"Producer").start(); } public void run() { int i = 0; while (true) { q.put(i++); } } class Consumer implements Runnable { Q q; Consumer(Q q) { this.q = q; new Thread(this, "Consumer").start(); } public void run() { while (true) { q.get(); } } class PC { public static void main(String args[]) { Q q = new Q(); new Producer(q); new Consumer(q); } Put: 1 Got: 1 Put: 2 Put: 3 Put: 4 Put: 5 Put: 6 Put: 7 Got: 7

Межпоточные связи class Q { int n; boolean valueSet = false; synchronized int get() { if (!valueSet) try { wait(); } catch(InterruptedException e) {}; System.out.println("Got: " + n); valueSet = false; notify(); return n; } synchronized void put(int n) { if (valueSet) try { wait(); } catch(InterruptedException e) {}; this.n = n; valueSet = true; System.out.println("Put: " + n); notify(); } Put: 1 Got: 1 Put: 2 Got: 2 Put: 3 Got: 3 Put: 4 Got: 4 Put: 5 Got: 5

Приостановка и возобновление потоков public static void main(String[] args) { RunnableThread obj1 = new RunnableThread("Первый"); RunnableThread obj2 = new RunnableThread("Второй"); try{ Thread.sleep(500) ; obj1.t.suspend(); System.out.println("Приостановка первого потока"); Thread.sleep(500) ; obj1.t.resume(); System.out.println("Перезапуск первого потока"); obj2.t.suspend(); System.out.println("Приостановка второго потока"); Thread.sleep(500) ; obj2.t.resume(); System.out.println("Перезапуск второго потока"); }catch(InterruptedException e){} try{ System.out.println("Ждет завершения потоков"); obj1.t.join(); obj2.t.join(); }catch(InterruptedException e){} System.out.println( "Завершение главного потока"); } public class RunnableThread implements Runnable { Thread t; public RunnableThread(String str) { t = new Thread(this,str); System.out.println("Новый поток: "+str); t.start(); } public void run() { for (int i = 0; i < 15; i++) { System.out.println(i + " " + t.getName()); try { Thread.sleep(200); } catch (InterruptedException e) {} } System.out.println("DONE! " + t.getName()); } Новый поток: Первый Новый поток: Второй 0 Первый 0 Второй 1 Второй 1 Первый 2 Второй 2 Первый Приостановка первого потока 3 Второй 4 Второй Перезапуск первого потока Приостановка второго потока 3 Первый 4 Первый DONE! Первый DONE! Второй Ждет завершения потоков Завершение главного потока

Приостановка и возобновление потоков void resume()resume перезапуск void stop() остановка void suspend() приостановка public void run() { try { for ( int i = 0; i < 20; i++ ) { System.out.println(name + " " + i); Thread.sleep(100); synchronized(this) { while(flag) { wait();} } } catch(Exception e){} System.out.println(name + " " + "End"); } public static void main(String [] a ) { T1 t11 = new T1 ("111"); t11.mysuspend(); T1 t12 = new T1 ("222"); try { Thread.sleep(20000); } catch(Exception e){} t11.myresume(); } class T1 implements Runnable { boolean flag = false; String name; T1(String n){ name = n; Thread t1 = new Thread(this,n); t1.start(); flag = false; } void mysuspend() { flag = true; } synchronized void myresume() { flag = false; notify(); }

Обмен данными между потоками while(!eof) { try { int iValue = in.readInt(); //читаем из потока System.out.println("read value = " + iValue); }catch(EOFException eofe) { eof = true; } } System.out.println("End of Data"); }catch (IOException ioe) {ioe.printStackTrace(); } } public static void main(String[] args) { try { final PipedOutputStream pos = new PipedOutputStream(); final PipedInputStream pis = new PipedInputStream(pos); Runnable runOutput = new Runnable() { public void run() { writeData(pos); } }; Thread outThread = new Thread(runOutput, "otThread"); outThread.start(); Runnable runInput = new Runnable() { public void run() { readData(pis); } }; Thread inThread = new Thread(runInput, "inThread"); inThread.start(); }catch (IOException ioe) { ioe.printStackTrace(); } } public class TestPipes { public TestPipes() { } public static void writeData(OutputStream os) { try { DataOutputStream out = new DataOutputStream( newBufferedOutputStream(os)); int[] numArray = { 1, 10, 2, 9, 3, 7, 4, 6, 5, 100, 200 }; for(int i=0; i

Поток с использованием внутреннего класса public class ThreadsDemo3 { String mesg; Thread t; int count; public static void main(String[] argv) { new ThreadsDemo3("Hello from X", 5); new ThreadsDemo3("Hello from Y", 10); } public ThreadsDemo3(String m, int n) { count = n; mesg = m; t = new Thread(new Runnable() { public void run() { while (count-- > 0) { println(mesg); try { Thread.sleep(100);// 100 msec } catch (InterruptedException e) {return;} } System.out.println (mesg + " thread all done."); }}); t.setName(m + " runner Thread"); t.start(); } Hello from X Hello from Y Hello from X Hello from Y Hello from X Hello from Y Hello from X Hello from Y Hello from X Hello from Y Hello from X thread all done. Hello from Y Hello from Y thread all done.

public class Animator extends Applet implements Runnable { int x; int y; boolean done; public void start() { done = false; new Thread(this).start(); } public void stop() { done = true; } public synchronized void run() { int width = getSize().width;// Get the framesize int height = getSize().height; x = (int)(Math.random() * width); y = (int)(Math.random() * height); while (!done) { width = getSize().width; height = getSize().height; if (x++ >= width) x=0;// return to shallow end if (y++ >= height) y=0; repaint();// Tell AWT to call our paint(). try { Thread.sleep(250); } catch (InterruptedException e) {return;} }} public void paint(Graphics g) { g.setColor(Color.red); g.fillRect(x, y, 10, 10); } Пример с анимацией в потоках