1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package org.spf4j.base;
33
34 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
35 import java.util.logging.Level;
36 import java.util.logging.Logger;
37 import javax.annotation.Nullable;
38
39
40
41
42
43 @SuppressFBWarnings("ACEM_ABSTRACT_CLASS_EMPTY_METHODS")
44 public abstract class AbstractRunnable implements Runnable {
45
46 @Deprecated
47 public static final int ERROR_EXIT_CODE = SysExits.EX_SOFTWARE.exitCode();
48
49
50 public static final Runnable NOP = () -> { };
51
52 private final boolean lenient;
53
54 private final String threadName;
55
56
57
58
59
60
61
62
63 public AbstractRunnable(final boolean lenient, @Nullable final String threadName) {
64 this.lenient = lenient;
65 this.threadName = threadName;
66 }
67
68
69
70
71
72
73
74 public AbstractRunnable(final boolean lenient) {
75 this(lenient, null);
76 }
77
78 public AbstractRunnable() {
79 this(false, null);
80 }
81
82 public AbstractRunnable(final String threadName) {
83 this(false, threadName);
84 }
85
86 @Override
87 public final void run() {
88 Thread thread = null;
89 String origName = null;
90 if (threadName != null) {
91 thread = Thread.currentThread();
92 origName = thread.getName();
93 thread.setName(threadName);
94 }
95
96 try {
97 doRun();
98 } catch (Exception ex) {
99 if (org.spf4j.base.Throwables.containsNonRecoverable(ex)) {
100 Runtime.goDownWithError(ex, SysExits.EX_SOFTWARE);
101 }
102 if (lenient) {
103 Logger.getLogger(AbstractRunnable.class.getName()).log(Level.SEVERE, "Exception in runnable: ", ex);
104 } else {
105 throw new UncheckedExecutionException(ex);
106 }
107 } catch (Throwable ex) {
108 if (org.spf4j.base.Throwables.containsNonRecoverable(ex)) {
109 Runtime.goDownWithError(ex, SysExits.EX_SOFTWARE);
110 }
111 throw ex;
112 } finally {
113 if (thread != null) {
114 thread.setName(origName);
115 }
116 }
117 }
118
119 public abstract void doRun() throws Exception;
120
121 }