多线程使用:模拟一次宇宙战争来,看看多线程的其中一种使用场景。
第一步(使用Runnable)
第一步,通过Runnable构建一个军队的线程,军队发动多次进攻,线程线程执行完便是军队战争结束
把控战争进度通过控制while循环实现
/**
* @author liuzonghua
* @Package top.maniy.util
* @Description:
* @date 2018/11/7 16:22
*/
public class ArmyRunnable implements Runnable{
//volatile保证了线程可以正确的读取其他线程写入的值
//可见性 JMM happens-before原型
volatile boolean keepRunning=true;
@Override
public void run() {
while (keepRunning){
for(int i=0;i<5;i++) {
System.out.println(Thread.currentThread().getName() + "进攻对方【" + i + "】");
//让出了处理时间,下次该谁进攻还不一定呢!
Thread.yield();
}
}
System.out.println(Thread.currentThread().getName()+"结束了战斗!");
}
}
第二步(Thread)
Runnable使用了,我们在使用一次Thread,来表示一个关键人物介绍这场战争
public class KeyPersonThread extends Thread{
@Override
public void run(){
System.out.println(Thread.currentThread().getName()+"开始了战斗!");
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+"释放奥义");
}
System.out.println(Thread.currentThread().getName()+"结束战斗");
}
}
第三步(战争舞台)
我们要把这些军队和关键人物搬上舞台来跑起来。
也就是线程的使用,这里可以把舞台也通过线程实现,便是线程调用线程的场景。
改变keepRunning 值来停止战争
public class Stage extends Thread {
@Override
public void run(){
System.out.println("欢迎观看多线程模拟宇宙战争");
//等待几秒吧
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("开始了");
ArmyRunnable armyRunnableOne =new ArmyRunnable();
ArmyRunnable armyRunnableTwo =new ArmyRunnable();
//使用Runnable接口创建线程
Thread armyOne = new Thread(armyRunnableOne,"弗利沙军队");
Thread armyTwo = new Thread(armyRunnableTwo,"白胡子第一军队");
//启动线程,让军队开始作战
armyOne.start();
armyTwo.start();
//舞台线程休眠,大家专心观看军队厮杀
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("双方停止战斗吧");
armyRunnableOne.keepRunning =false;
armyRunnableTwo.keepRunning=false;
try {
armyOne.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("激战之中,出现boss");
Thread boss =new KeyPersonThread();
boss.setName("奥利哈刚的巨神兵");
System.out.println("我要结束一切");
armyRunnableOne.keepRunning =false;
armyRunnableTwo.keepRunning=false;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
boss.start();
try {
boss.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("一切将会结束");
System.out.println("宇宙战争结束");
}
public static void main(String[] args){
new Stage().start();
}
}
知识点
一、volatile关键字
一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
2)禁止进行指令重排序。
二、Thread.yield();
当调用Thread.yield()方法时,会给线程调度器一个当前线程愿意让出CPU使用的暗示,但是线程调度器可能会忽略这个暗示.
说白话,就是线程暂停允许执行其他线程(包括自己),我把球丢在空中,大家一起抢。
三、t.join();
t.join()方法会使所有线程都暂停并等待t的执行完毕。这里等待军队线程结束后,在执行关键人物线程。