当前位置:嗨网首页>书籍在线阅读

36-案例实现

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

案例实现

根据如下步骤来实现本例。

1.创建一个 Flag 类,并创建一个布尔型的 flag 公有字段且默认值为 true

public class Flag {
  public boolean flag=true;
}

2.创建一个 VolatileFlag 类,并创建一个布尔型的 flag 公有字段且默认值为 true 。添加 volatile 修饰符到该字段的声明上:

public class VolatileFlag {
  public volatile boolean flag=true;
}

3.创建一个 Task 类并实现 Runnable 接口。它使用一个 Flag 的私有字段和一个构造方法来初始化它:

public class Task implements Runnable {
  private Flag flag;
  public Task(Flag flag) {
    this.flag = flag;
  }

4.实现该任务的 run() 方法。当 flag 值为 true 时,它将自增一个整型变量。然后,写回变量的最终值:

@Override
public void run() {
  int i = 0;
  while (flag.flag) {
    i++;
  }
  System.out.printf("VolatileTask: Stopped %d - %s\n", i,
                    new Date());
}

5.创建一个 VolatileTask 类并实现 Runnable 接口。它使用一个 VolatileFlag 私有字段和一个构造方法来初始化它:

public class VolatileTask implements Runnable {
  private VolatileFlag flag;
  public VolatileTask(VolatileFlag flag) {
    this.flag = flag;
  }

6.实现该任务的 run() 方法。因为这与前一个 Task 类相等,所以代码细节将不会在这里展示。

7.实现 Main 类及其 main() 方法。首先,创建4个类型对象,它们分别为 Volatile-FlagFlagVolatileTaskTask

public class Main {
  public static void main(String[] args) {
    VolatileFlag volatileFlag=new VolatileFlag();
    Flag flag=new Flag();
    VolatileTask vt=new VolatileTask(volatileFlag);
    Task t=new Task(flag);

8.然后,创建两个线程来执行该任务,并启动它们,然后阻塞主线程1s:

Thread thread=new Thread(vt);
thread.start();
thread=new Thread(t);
thread.start();
try {
  TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
  e.printStackTrace();
}

9.然后,改变 volatileFlag 变量值来停止 VolatileTask 的执行,并且阻塞主线程1s:

System.out.printf("Main: Going to stop volatile task: %s\n",
                  new Date());
volatileFlag.flag=false;
System.out.printf("Main: Volatile task stopped: %s\n", new Date());
try {
  TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
  e.printStackTrace();
}

10.最后,改变任务对象的值来停止任务执行,并且阻塞主线程1s:

System.out.printf("Main: Going to stop task: %s\n", new Date());
flag.flag=false;
System.out.printf("Main: Volatile stop flag changed: %s\n",
                  new Date());
try {
  TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
  e.printStackTrace();
}