Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // 1. Let's start a thread and try to interrupt it:
- object Main extends App {
- val thread = new Thread(() => {
- println("Hello")
- Thread.sleep(5000) // wait, join or sleep
- println("Bye")
- })
- thread.setDaemon(true)
- thread.start()
- println("Press ENTER to interrupt")
- StdIn.readLine()
- thread.interrupt()
- println(s"Thread interrupted = ${thread.isInterrupted}")
- println("Press ENTER to finish")
- StdIn.readLine()
- println("End")
- }
- // Output if (t > 5 sec) => nothing happened:
- // Hello
- // Press ENTER to interrupt
- // Bye
- // Thread interrupted = false
- // Press ENTER to finish
- // End
- // Output if (t < 5 sec) => exception:
- // Press ENTER to interrupt
- // Hello
- // Exception in thread "Thread-0" java.lang.InterruptedException: sleep interrupted
- // at java.lang.Thread.sleep(Native Method)
- // at ru.mitrakov.self.sandbox.Main$.$anonfun$thread$1(Main.scala:16)
- // at java.lang.Thread.run(Thread.java:745)
- // Thread interrupted = false
- // Press ENTER to finish
- // End
- // 2. Now let's wrap everything with try-catch:
- object Main extends App {
- try {
- val thread = new Thread(() => {
- println("Hello")
- Thread.sleep(5000) // wait, join or sleep
- println("Bye")
- })
- thread.setDaemon(true)
- thread.start()
- println("Press ENTER to interrupt")
- StdIn.readLine()
- thread.interrupt()
- println(s"Thread interrupted = ${thread.isInterrupted}")
- println("Press ENTER to finish")
- StdIn.readLine()
- println("End")
- } catch {
- case th: Throwable => println(s"ERROR! $th")
- }
- }
- // Output if (t < 5 sec): still exception!
- // Press ENTER to interrupt
- // Hello
- // Exception in thread "Thread-0" java.lang.InterruptedException: sleep interrupted
- // at java.lang.Thread.sleep(Native Method)
- // at ru.mitrakov.self.sandbox.Main$.$anonfun$new$1(Main.scala:17)
- // at java.lang.Thread.run(Thread.java:745)
- // Thread interrupted = false
- // Press ENTER to finish
- // End
- // 3. What happened? The problem is that we have to wrap only the thread code with try-catch!
- object Main extends App {
- val thread = new Thread(() => {
- try {
- println("Hello")
- Thread.sleep(5000) // wait, join or sleep
- println("Bye")
- } catch {
- case th: Throwable => println(s"ERROR! $th")
- }
- })
- thread.setDaemon(true)
- thread.start()
- println("Press ENTER to interrupt")
- StdIn.readLine()
- thread.interrupt()
- println(s"Thread interrupted = ${thread.isInterrupted}")
- println("Press ENTER to finish")
- StdIn.readLine()
- println("End")
- }
- // Output if (t < 5 sec):
- // Press ENTER to interrupt
- // Hello
- // ERROR! java.lang.InterruptedException: sleep interrupted
- // Thread interrupted = false
- // Press ENTER to finish
- // End
- // 4. OK, much better, but we know that we should use NonFatal pattern instead of catching everything:
- } catch {
- case NonFatal(e) => println(s"ERROR! $e")
- }
- // Output if (t < 5 sec): exception!
- // Press ENTER to interrupt
- // Hello
- // Exception in thread "Thread-0" java.lang.InterruptedException: sleep interrupted
- // at java.lang.Thread.sleep(Native Method)
- // at ru.mitrakov.self.sandbox.Main$.$anonfun$thread$1(Main.scala:17)
- // at java.lang.Thread.run(Thread.java:745)
- // Thread interrupted = false
- // Press ENTER to finish
- // End
- // 6. The problem is that NonFatal considers InterruptedException as a fatal one; let's fix it:
- } catch {
- case NonFatal(e) | ie: InterruptedException => println(s"ERROR! ${e.getMessage}")
- }
- // Output: compilation error
- // 7. It's impossible in Scala. Let's re-write it:
- } catch {
- case NonFatal(e) => println(s"ERROR! ${e.getMessage}")
- case e: InterruptedException => println(s"INTERRUPTED! ${e.getMessage}")
- }
- // Output if (t < 5 sec):
- // Hello
- // Press ENTER to interrupt
- // Thread interrupted = false
- // Press ENTER to finish
- // INTERRUPTED! sleep interrupted
- // End
- // 8. Now everything works, except one little thing: why "Thread interrupted = false"?
- // All we need to do is to restore interruption flag (see JavaDoc to Thread#interrupt())
- case e: InterruptedException => Thread.currentThread().interrupt(); println(s"INTERRUPTED! ${e.getMessage}")
- // Output if (t < 5 sec):
- // Press ENTER to interrupt
- // Hello
- // Thread interrupted = true
- // Press ENTER to finish
- // INTERRUPTED! sleep interrupted
- // End
- // Summary:
- // if you don't work with manual threads interruption and don't use sleep/wait/join manipulations => just skip
- // matching InterruptedException (even if something changes in the future, just let it crash)
- // if you do work with manual threads interruption and sleep/wait/join are possible => handle it and restore
- // interruption flag, so that caller could handle this accordingly.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement