Chair of Software Engineering Java and C# in Depth Prof. Dr. Bertrand Meyer Exercise Session 8 Nadia Polikarpova
Quiz 1: What is printed? (Java) class MyTask implements Runnable { � «Everything is ok! � � public void run() { � Exception in thread...: Help!» � � � throw new RuntimeException("Help!"); � � } � } � Exceptions from other threads are not propagated to main � public static void main(String[] args) { � � try { � � � (new Thread(new MyTask())).start(); � � � System.out.println("Everything is ok!"); � � } catch (RuntimeException e) { � � � System.out.println("Something went wrong..."); � � } � } � Java and C# in depth 2
Quiz 1: A C# solution In C# you can use asynchronous delegates to propagate exceptions to the main thread: � static void MyTask() { throw new Exception("Help!"); } � delegate void MyTaskInvoker(); � public static void Main() { � try { � MyTaskInvoker method = MyTask; � IAsyncResult res = method.BeginInvoke(null, null); � method.EndInvoke(res); � � � // This doesn � t work: � // new Thread(MyTask).Start(); � } catch (Exception) { � Console.WriteLine("Something went wrong"); � } � Java and C# in depth 3
Quiz 2: What happens (C#)? static void MyTask() { � � try { � � � ... // Some heavy work � � } catch { ... � � } fi nally { � � � Console.WriteLine("Very important cleanup"); � � } � finally block may not be executed: } � the main thread may exit before that and the application does not wait for public static void Main() { � background threads to fi nish � � Thread t = new Thread(MyTask); � � t.IsBackground = true; � � t.Start(); � � ... � � t.Interrupt(); �� } � Java and C# in depth 4
Quiz 3: What can go wrong? (Java) public walkUnderTheRain() { � Shared variable � � if(!isRaining) { � � � try { wait(); } � � � catch (InterruptedException e) {} � � } � � System.out.println("Walking under the rain!"); � } � Don � t expect that the fi rst interrupt we get is the one we need: use while instead of if � To call wait the enclosing method must be synchronized � (otherwise IllegalMonitorStateException is thrown at runtime) � Java and C# in depth 5
Quiz 3: A C# solution: wait handles static EventWaitHandle rain = new AutoResetEvent(false); � static void WalkUnderTheRain() { � � rain.WaitOne(); � � Console.WriteLine("Walking under the rain!”); � } � public static void Main() { � � new Thread(WalkUnderTheRain).Start(); � � Thread.Sleep(500); � � rain.Set(); � } � Java and C# in depth 6
Quiz 4.a: What happens? (Java) class MyTask implements Runnable { � � public void run() { � run does not handle interrupts � � � while (true) { } � � } � } � public static void main(String[] args) { � � try { � � � Thread t = new Thread(new MyTask()); � � � t.start(); � this code is never executed � � � t.interrupt(); � � � t.join(); � � � System.out.println("t interrupted"); � � } catch (InterruptedException e) {} � } � Java and C# in depth 7
Quiz 4.a: How to handle interrupts? 1. Calling methods that throw InterruptedException � public synchronized void run() { � � while (true) try { � � � sleep (200); � � } catch (InterruptedException e) { � � � return; � � } � } � 2. Checking Thread.interrupted fl ag � public void run() { � � while (true) { � � � if (Thread.interrupted()) { return; } � � } � } � Java and C# in depth 8
Quiz 4.b: What happens? (C#) static void Run() { while (true) { } } � public static void Main() { � � Thread t = new Thread(Run); � � t.Start(); � � Thread.Sleep(500); � � t.Abort(); � � t.Join(); � � Console.WriteLine("t aborted"); � } � This code is executed. � Unlike Interrupt , Abort stops the thread even if it � s currently running � Java and C# in depth 9
Quiz 4.c: What happens (C#)? static void Run() { � � while (true) { � � � try { � � � Thread.Sleep(1000); � � � } catch (ThreadAbortException e) { � � � Console.WriteLine("Ha-ha! I will be executing FOREVER!"); � � � } � � } � } � Thread t is still aborted! � ThreadAbortException is automatically public static void Main() { � rethrown at the end of the catch block if � Thread t = new Thread(Run); � Thread.ResetAbort is not called � � t.Start(); � � Thread.Sleep(500); � � t.Abort(); � � t.Join(); � � Console.WriteLine("t aborted"); � } � Java and C# in depth 10
Quiz 5: Is this class thread-safe? (Java) class Counter { � Counter count = new Counter; � private int c = 0; � ... � // In thread 1: � public void increment() { � count.increment(); � c++; � ... � } � // In thread 2: � count.increment(); � public void decrement() { � ... � c--; � // In the main thread after joining � } � // threads 1 and 2: � System.out.println(count.value()); � public int value() { � c++ is not atomic => � return c; � } � the result might be 1 � } � Java and C# in depth 11
Quiz 5: Is this class thread-safe? (Java) All attributes must be accessible only through class Counter { � synchronized methods � public int c = 0; � private � public synchronized void increment() { � c++; � } � public synchronized void decrement() { � c--; � } � public synchronized int value() { � return c; � } � } � Java and C# in depth 12
Quiz 5: Is this class thread-safe? (Java) class Counter { � � ... // Everything as before � � public static synchronized void increment_some(Counter count) { � � � count.c++; � No: static methods use different � } � object as a lock! � � Counter(int c) { � OK: constructors need not (and � � this.c = c; � cannot) be synchronized, they � } � are executed once per object � } � Java and C# in depth 13
Quiz 6: What is printed? (Java) public class BadThreads { � � static String message; � � private static class CorrectorThread extends Thread { � � � public void run() { � � � � try { sleep(1000); } catch (InterruptedException e) {} � � � � message = "Mares do eat oats."; � � � } � � } � � public static void main(String args[]) throws InterruptedException { � � � (new CorrectorThread()).start(); � � � message = "Mares do not eat oats."; � � � Thread.sleep(2000); � How to ensure that “Mares do � � System.out.println(message); � eat oats” is always printed? � � } � } � Java and C# in depth 14
Quiz 6: Solutions 1. Join the CorrectorTread � public static void main(String args[]) throws InterruptedException { � � CorrectorThread ct = new CorrectorThread(); ct.start(); � �� � message = "Mares do not eat oats."; � � ct.join(); � � System.out.println(message); � } � 2. Declare massage as volatile ? � Guarantees that the 2 threads see the same value of message, but does not guarantee that � � message = "Mares do eat oats."; � is executed before � � System.out.println(message); � (it is not guaranteed that sleep (2000) takes longer than sleep (1000) ) � Java and C# in depth 15
Quiz 7: Does it work? (C#) volatile static bool go; � volatile static DateTime dt; � static void Wait() { � Here we want to see the change while (!go) { } � to dt made by the main thread � Console.WriteLine(dt); � } � Compilation error: � Objects of non-primitive value types public static void Main() { � cannot be cached by the processor => need not (and cannot) be volatile � � new Thread(Wait).Start(); � � Thread.Sleep(1000); � � dt = DateTime.Now; � � go = true; � } � Java and C# in depth 16
Questions? Java and C# in depth 17
Recommend
More recommend