如果把Stage類中的armyTaskOfSuiDynasty和armyTaskOfRevolt對keepRunning的修改注釋掉第二個,根據volatile的實現原理,第一個對象對keepRunning的修改并把最新值刷入內存中,為什么armyOfRevolt沒有讀取到最新值,還是讀取了自己對象內的值false。使得不能停止armyOfRevolt線程。
package com.concurrent.base;
//軍隊線程模擬作戰雙方的行為
public class ArmyRunnable implements Runnable{
?? ?//volatile保證了線程可以正確的去讀取其它線程寫入的值。
?? ?//可見性。當前類及其同包中的類。
?? ?volatile boolean keepRunning=true;
?? ?@Override
?? ?
?? ?public void run(){
?? ??? ?while(keepRunning){
?? ??? ??? ?//發動5連擊
?? ??? ??? ?for(int i=0;i<5;i++){
?? ??? ??? ??? ?System.out.println(Thread.currentThread().getName()+"進攻對方["+i+"]");
?? ??? ??? ??? ?//讓出了處理器時間
?? ??? ??? ??? ?Thread.yield();
?? ??? ??? ?}
?? ??? ?}
?? ??? ?System.out.println(Thread.currentThread().getName()+"結束了戰斗!");
?? ?}
}
package com.concurrent.base;
public class Stage extends Thread {
?? ?public void run(){
?? ??? ?
?? ??? ?System.out.println("歡迎觀看隋唐演義");
?? ??? ?
?? ??? ?
?? ??? ?try {
?? ??? ??? ?Thread.sleep(5000);
?? ??? ?} catch (InterruptedException e1) {
?? ??? ??? ?e1.printStackTrace();
?? ??? ?}
?? ??? ?
?? ??? ?System.out.println("大幕徐徐拉開");
?? ??? ?
?? ??? ?try {
?? ??? ??? ?Thread.sleep(5000);
?? ??? ?} catch (InterruptedException e1) {
?? ??? ??? ?e1.printStackTrace();
?? ??? ?}
?? ??? ?System.out.println("話說隋朝末年,隋軍和農民起義軍殺得天昏地暗");
?? ??? ?ArmyRunnable armyTaskOfSuiDynasty=new ArmyRunnable();//定義了4個對象
?? ??? ?ArmyRunnable armyTaskOfRevolt=new ArmyRunnable();
?? ??? ?
?? ??? ?//使用Runnable接口創建線程
?? ??? ?Thread armyOfSuiDynasty=new Thread(armyTaskOfSuiDynasty,"隋軍");
?? ??? ?Thread armyOfRevolt=new Thread(armyTaskOfRevolt,"農民起義軍");
?? ??? ?
?? ??? ?
?? ??? ?//啟動線程,讓軍隊開始作戰
?? ??? ?armyOfSuiDynasty.start();
?? ??? ?armyOfRevolt.start();
?? ??? ?
?? ??? ?//舞臺線程休眠,大家專心觀看軍隊的廝殺。
?? ??? ?try {
?? ??? ??? ?Thread.sleep(50);
?? ??? ?} catch (InterruptedException e) {
?? ??? ??? ?e.printStackTrace();
?? ??? ?}
?? ??? ?armyTaskOfSuiDynasty.keepRunning=false;
?? ??? ?armyTaskOfRevolt.keepRunning=false;
//?? ??? ?armyOfSuiDynasty.stop();
//?? ??? ?armyOfRevolt.stop();
?? ??? ?
?? ??? ?try {
?? ??? ??? ?armyOfRevolt.join();
?? ??? ?} catch (InterruptedException e) {
?? ??? ??? ?e.printStackTrace();
?? ??? ?}
?? ??? ?System.out.println("正當雙發激戰正酣,半路殺出了個程咬金");
?? ??? ?
?? ??? ?Thread mrCheng=new KeyPersonThread();
?? ??? ?mrCheng.setName("程咬金");
?? ??? ?System.out.println("程咬金的理想就是結束戰爭,使百姓安居樂業!");
?? ??? ?
?? ??? ?//停止線程
?? ??? ?armyTaskOfSuiDynasty.keepRunning=false;
?? ??? ?armyTaskOfRevolt.keepRunning=false;
?? ??? ?try {
?? ??? ??? ?Thread.sleep(2000);
?? ??? ?} catch (InterruptedException e) {
?? ??? ??? ?// TODO Auto-generated catch block
?? ??? ??? ?e.printStackTrace();
?? ??? ?}
?? ??? ?mrCheng.start();
?? ??? ?
?? ??? ?try {
?? ??? ??? ?mrCheng.join();
?? ??? ?} catch (InterruptedException e) {
?? ??? ??? ?e.printStackTrace();
?? ??? ?}//
?? ??? ?System.out.println("戰爭結束,人民安居樂業,程先生實現了積極的人生夢想,為人民做出了貢獻");//這語句也被當作線程來處理。當
?? ??? ?//注釋掉mrCheng.join代碼塊時,這兩個線程先得到執行。后再執行mrCheng.start()語句//調用存在執行時間
?? ??? ?System.out.println("謝謝觀看隋唐演義,再見!");
?? ?}
?? ?public static void main(String[] args) {
?? ??? ?Stage demo=new Stage();
?? ??? ?demo.start();
?? ??? ?
?? ?}
}