- 當我們想要結束一個線程或者關閉jvm的時候,通過此模式可以優雅安全的關閉線程,讓線程可以完成它本應完成的當前任務並可以附加一些收尾工作後再進行關閉
- 此模式下關閉線程會有一定延遲,主要在於被關閉線程需要執行完後,再進行關閉
- 首先Java jdk中並沒有關於安全的直接的停止線程的Api 我知道你想到了Interrupt
public class s1 {
public volatile static int v1 = 0;
public static int v2 = 0;
public static int v3 = 0;
public volatile static int v4 = 0;
public static AtomicInteger v5 = new AtomicInteger(0);
public static void inc() {
try {
Thread.sleep(3);
} catch (InterruptedException e) {
}
v1++;
v2++;
v5.getAndIncrement();
synchronized (s1.class) {
v3++;
v4++;
}
}
public static void main(String[] args) throws InterruptedException {
Thread threads[]=new Thread[1000];
for (int i = 0; i < 1000; i++) {
threads[i]=new Thread(new Runnable() {
@Override
public void run() {
inc();
}
});
threads[i].start();
}
for(Thread t:threads)
t.join();
System.out.println("運行結果v1:Counter.count=" + s1.v1);
System.out.println("運行結果v2:Counter.count=" + s1.v2);
System.out.println("運行結果v3:Counter.count=" + s1.v3);
System.out.println("運行結果v4:Counter.count=" + s1.v4);
System.out.println("運行結果v5:Counter.count=" + s1.v5);
}
}
運行結果v2:Counter.count=998
運行結果v3:Counter.count=1000
運行結果v4:Counter.count=1000
運行結果v5:Counter.count=1000
/**
*
* @author Allen
* @date 2017年2月21日
*
*/
public class e1 implements Runnable {
private volatile boolean closeThread = false;
private int i;
// 終止請求
public void shutdownRequest() {
closeThread = true;
Thread.currentThread().interrupt();
}
public void close() {
this.closeThread = true;
}
public boolean isCloseThread() {
return closeThread;
}
// 具體動作
public final void run() {
try {
while (!closeThread) {
System.out.println("維修進度" + ++i + "%");
Thread.sleep(1);
}
} catch (InterruptedException e) {
} finally {
try {
overFun();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 終止處理
private void overFun() throws InterruptedException {
Thread.sleep(1000);
System.out.println(">>>>>正在收拾工具");
Thread.sleep(1000);
System.out.println(">>>>>正在把瑪莎拉蒂開出車庫");
Thread.sleep(1000);
System.out.println(">>>>>正在用瑪莎拉蒂車載電話呼叫領導的手機");
Thread.sleep(1000);
System.out.println(">>>>>我:領導你好,土豪我今天的總維修進度 " + i + "%");
}
}
public static void main(String[] args) {
System.out.println("開始修電腦");
try {
e1 e = new e1();
Thread t = new Thread(e);
t.start();
Thread.sleep(new Random().nextInt(30)+69);
System.out.println("大喇叭廣播: ~都快別修了");
e.close();
t.join();
System.out.println("領導:..你居然開瑪莎拉蒂");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
維修進度1%
維修進度2%
維修進度3%
維修進度40%
維修進度41%
維修進度42%
維修進度43%
大喇叭廣播: ~都快別修了
>>>>>正在收拾工具
>>>>>正在把瑪莎拉蒂開出車庫
>>>>>正在用瑪莎拉蒂車載電話呼叫領導的手機
>>>>>我:領導你好,開着瑪莎拉蒂的我今天總維修進度 43%
領導:..你居然開瑪莎拉蒂
package TwoPhaseTerminationPattern.complex.sys.inf;
import TwoPhaseTerminationPattern.complex.ThreadOverException;
/**
* 遊戲系統
* @author Administrator
*
*/
public abstract class IGameSys {
private long time;
private String name;
public IGameSys(long time, String name) {
this.time = time;
this.name = name;
}
public String name() {
return this.name;
}
public long time() {
return this.time;
}
public abstract void event(Object... ob) throws ThreadOverException;
public abstract void overEvent();
}
package TwoPhaseTerminationPattern.complex.sys;
import TwoPhaseTerminationPattern.complex.ThreadOverException;
import TwoPhaseTerminationPattern.complex.sys.inf.IGameSys;
/**
* 活動系統實現
*
* @author Allen
* @date 2017年2月21日
*
*/
public class ActivitySys extends IGameSys {
public ActivitySys(long time, String name) {
super(time, name);
}
private boolean temp = false;
@Override
public void event(Object... ob) throws ThreadOverException {
if (!temp){
System.out.println("<Thread-" + super.name() + ">[event]活動系統運行中 ><");
temp=true;
}
}
@Override
public void overEvent() {
System.out.println("<Thread" + super.name() + ">[overEvent]");
}
}
package TwoPhaseTerminationPattern.complex.sys;
import TwoPhaseTerminationPattern.complex.ThreadOverException;
import TwoPhaseTerminationPattern.complex.sys.inf.IGameSys;
/**
* 公告系統實現
*
* @author Allen
* @date 2017年2月21日
*
*/
public class MsgSys extends IGameSys {
public MsgSys(long time, String name) {
super(time, name);
}
private boolean temp=false;
@Override
public void event(Object... ob) throws ThreadOverException {
if (!temp){
System.out.println("<Thread-" + super.name() + ">[event]系統公告運行中 ><");
temp=true;
}
}
@Override
public void overEvent() {
System.out.println("<Thread" + super.name() + ">[overEvent]");
}
}
package TwoPhaseTerminationPattern.complex;
public interface IRepairModel extends Runnable {
}
package TwoPhaseTerminationPattern.complex;
import TwoPhaseTerminationPattern.complex.sys.inf.IGameSys;
public class RepairModelImpl implements IRepairModel {
private IGameSys ir;
public RepairModelImpl(IGameSys ir) {
this.ir = ir;
}
@Override
public void run() {
System.out.println(ir.name() + "已啓動");
try {
while (true) {
Thread.sleep(ir.time());
if (SystemState.getInstance().isState())
break;
ir.event();
}
} catch (ThreadOverException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
ir.overEvent();
}
return;
}
}
package TwoPhaseTerminationPattern.complex;
import java.util.Arrays;
import java.util.Iterator;
import TwoPhaseTerminationPattern.complex.sys.ActivitySys;
import TwoPhaseTerminationPattern.complex.sys.MsgSys;
import TwoPhaseTerminationPattern.complex.sys.inf.IGameSys;
/**
*
* @author Allen
* @date 2017年2月22日
*
*/
public class run {
static IGameSys[] igame = {
new MsgSys(500,"公告系統"),
new ActivitySys(200,"活動系統")
};
public static void main(String[] args) throws InterruptedException {
System.out.println("遊戲服務器已啓動");
startThreadGroup();
Thread.sleep(4000);
SystemState.getInstance().sendState();
}
private static void startThreadGroup() throws InterruptedException {
Iterator<IGameSys> it = Arrays.asList(igame).iterator();
while (it.hasNext()) {
Thread thread = new Thread(new RepairModelImpl(it.next()));
thread.start();
}
}
}
package TwoPhaseTerminationPattern.complex;
/**
* 修復狀態
*
* @author Allen
* @date 2017年2月21日
*
*/
public final class SystemState {
/**
* 餓漢單例
*/
private static SystemState instance = new SystemState();
private SystemState() {
}
public static SystemState getInstance() {
return instance;
}
private volatile boolean state = false;
public boolean isState() {
return state;
}
/**
* 發送狀態
* @author Allen
* @date 2017年2月21日
*/
public void sendState() {
this.state = true;
}
}
package TwoPhaseTerminationPattern.complex;
public class ThreadOverException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
}
輸出結果:公告系統已啓動
活動系統已啓動
<Thread-活動系統>[event]活動系統運行中 ><
<Thread-公告系統>[event]系統公告運行中 ><
<Thread活動系統>[overEvent]
<Thread公告系統>[overEvent]
IGameSys 系統服務模型