Advertisement
mitrakov

Scala: InterruptedException

Feb 6th, 2018
322
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 4.77 KB | None | 0 0
  1. // 1. Let's start a thread and try to interrupt it:
  2. object Main extends App {
  3.   val thread = new Thread(() => {
  4.     println("Hello")
  5.     Thread.sleep(5000) // wait, join or sleep
  6.     println("Bye")
  7.   })
  8.   thread.setDaemon(true)
  9.   thread.start()
  10.  
  11.   println("Press ENTER to interrupt")
  12.   StdIn.readLine()
  13.   thread.interrupt()
  14.   println(s"Thread interrupted = ${thread.isInterrupted}")
  15.  
  16.   println("Press ENTER to finish")
  17.   StdIn.readLine()
  18.   println("End")
  19. }
  20.  
  21. // Output if (t > 5 sec) => nothing happened:
  22. // Hello
  23. // Press ENTER to interrupt
  24. // Bye
  25.  
  26. // Thread interrupted = false
  27. // Press ENTER to finish
  28.  
  29. // End
  30.  
  31.  
  32.  
  33. // Output if (t < 5 sec) => exception:
  34. // Press ENTER to interrupt
  35. // Hello
  36.  
  37. // Exception in thread "Thread-0" java.lang.InterruptedException: sleep interrupted
  38. //  at java.lang.Thread.sleep(Native Method)
  39. //  at ru.mitrakov.self.sandbox.Main$.$anonfun$thread$1(Main.scala:16)
  40. //  at java.lang.Thread.run(Thread.java:745)
  41. // Thread interrupted = false
  42. // Press ENTER to finish
  43.  
  44. // End
  45.  
  46.  
  47.  
  48. // 2. Now let's wrap everything with try-catch:
  49. object Main extends App {
  50.   try {
  51.     val thread = new Thread(() => {
  52.       println("Hello")
  53.       Thread.sleep(5000) // wait, join or sleep
  54.       println("Bye")
  55.     })
  56.     thread.setDaemon(true)
  57.     thread.start()
  58.  
  59.     println("Press ENTER to interrupt")
  60.     StdIn.readLine()
  61.     thread.interrupt()
  62.     println(s"Thread interrupted = ${thread.isInterrupted}")
  63.  
  64.     println("Press ENTER to finish")
  65.     StdIn.readLine()
  66.     println("End")
  67.   } catch {
  68.     case th: Throwable => println(s"ERROR! $th")
  69.   }
  70. }
  71.  
  72. // Output if (t < 5 sec): still exception!
  73. // Press ENTER to interrupt
  74. // Hello
  75.  
  76. // Exception in thread "Thread-0" java.lang.InterruptedException: sleep interrupted
  77. //  at java.lang.Thread.sleep(Native Method)
  78. //  at ru.mitrakov.self.sandbox.Main$.$anonfun$new$1(Main.scala:17)
  79. //  at java.lang.Thread.run(Thread.java:745)
  80. // Thread interrupted = false
  81. // Press ENTER to finish
  82.  
  83. // End
  84.  
  85.  
  86.  
  87. // 3. What happened? The problem is that we have to wrap only the thread code with try-catch!
  88. object Main extends App {
  89.   val thread = new Thread(() => {
  90.     try {
  91.       println("Hello")
  92.       Thread.sleep(5000) // wait, join or sleep
  93.       println("Bye")
  94.     } catch {
  95.       case th: Throwable => println(s"ERROR! $th")
  96.     }
  97.   })
  98.   thread.setDaemon(true)
  99.   thread.start()
  100.  
  101.   println("Press ENTER to interrupt")
  102.   StdIn.readLine()
  103.   thread.interrupt()
  104.   println(s"Thread interrupted = ${thread.isInterrupted}")
  105.  
  106.   println("Press ENTER to finish")
  107.   StdIn.readLine()
  108.   println("End")
  109. }
  110.  
  111. // Output if (t < 5 sec):
  112. // Press ENTER to interrupt
  113. // Hello
  114.  
  115. // ERROR! java.lang.InterruptedException: sleep interrupted
  116. // Thread interrupted = false
  117. // Press ENTER to finish
  118.  
  119. // End
  120.  
  121.  
  122.  
  123. // 4. OK, much better, but we know that we should use NonFatal pattern instead of catching everything:
  124. } catch {
  125.   case NonFatal(e) => println(s"ERROR! $e")
  126. }
  127.  
  128. // Output if (t < 5 sec): exception!
  129. // Press ENTER to interrupt
  130. // Hello
  131.  
  132. // Exception in thread "Thread-0" java.lang.InterruptedException: sleep interrupted
  133. //  at java.lang.Thread.sleep(Native Method)
  134. //  at ru.mitrakov.self.sandbox.Main$.$anonfun$thread$1(Main.scala:17)
  135. //  at java.lang.Thread.run(Thread.java:745)
  136. // Thread interrupted = false
  137. // Press ENTER to finish
  138.  
  139. // End
  140.  
  141.  
  142.  
  143. // 6. The problem is that NonFatal considers InterruptedException as a fatal one; let's fix it:
  144. } catch {
  145.   case NonFatal(e) | ie: InterruptedException => println(s"ERROR! ${e.getMessage}")
  146. }
  147.  
  148. // Output: compilation error
  149.  
  150.  
  151.  
  152. // 7. It's impossible in Scala. Let's re-write it:
  153. } catch {
  154.   case NonFatal(e) => println(s"ERROR! ${e.getMessage}")
  155.   case e: InterruptedException => println(s"INTERRUPTED! ${e.getMessage}")
  156. }
  157.  
  158. // Output if (t < 5 sec):
  159. // Hello
  160. // Press ENTER to interrupt
  161.  
  162. // Thread interrupted = false
  163. // Press ENTER to finish
  164. // INTERRUPTED! sleep interrupted
  165.  
  166. // End
  167.  
  168.  
  169.  
  170. // 8. Now everything works, except one little thing: why "Thread interrupted = false"?
  171. // All we need to do is to restore interruption flag (see JavaDoc to Thread#interrupt())
  172. case e: InterruptedException => Thread.currentThread().interrupt(); println(s"INTERRUPTED! ${e.getMessage}")
  173.  
  174. // Output if (t < 5 sec):
  175. // Press ENTER to interrupt
  176. // Hello
  177.  
  178. // Thread interrupted = true
  179. // Press ENTER to finish
  180. // INTERRUPTED! sleep interrupted
  181.  
  182. // End
  183.  
  184.  
  185.  
  186. // Summary:
  187. // if you don't work with manual threads interruption and don't use sleep/wait/join manipulations => just skip
  188. // matching InterruptedException (even if something changes in the future, just let it crash)
  189. // if you do work with manual threads interruption and sleep/wait/join are possible => handle it and restore
  190. // interruption flag, so that caller could handle this accordingly.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement