您的位置:首页 > 编程语言 > Java开发

26、Java入门—多线程之隋唐演义小案例

2016-11-01 11:46 519 查看
隋唐演义三个对象:

军队-ArmyRunnable;

英雄人物-KeyPersonThread;

舞台-Stage

//军队线程

//模拟作战双方行为

public class ArmyRunnable implements Runnable{

   ArmyRunnable armyTaskOfSuiDynasty = new ArmyRunnable();

   ArmyRunnable armyTaskOfarmyOfRevolt = new ArmyRunnable();

//使用Runnable 接口创建线程

Thread armyOfSuiDynasty = new Thread(armyTaskOfSuiDynasty,"隋军");

Thread armyOfRevolt = new Thread(armyTaskOfarmyOfRevolt,"农民起义军");



当线程并不是继承了Thread类而是实现了Runnable接口时,runnable中并没有getName()等方法,这时若想要调用这些方法就需要通过Thread类的静态方法currentThread()来获取当前线程的实体再调用。

在一个.java文件中能有多个类,但只能有一个public类(外部类)

为什么不调用run方法?

你可以理解为,run方法仅仅提供了业务逻辑,而线程运行是有更复杂要求的。这一切都封装在了Thread内部。所以记住一定不要自己调用run,而是调用start方法。

public class Actor extends Thread {

public void run() {
boolean running=true;
int count=0;
while(running){
System.out.println(getName()+"登台演出"+(++count));
if(count==50){
running=false;
}
if(count%10==0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Thread actor=new Actor();
actor.setName("Mr.Thread");
actor.start();
Thread actress=new Thread(new Actress(),"Ms.Runnable");
actress.start();
}

}

 class  Actress implements Runnable{
public void run() {
boolean running=true;
int count=0;
while(running){
System.out.println(Thread.currentThread().getName()+"登台演出"+(count++));
if(count==50){
running=false;
}
if(count%10==0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

}

此处++count若改成count++  结果是 0-9  10-19......90-99  结束

1:创建线程的方法有两种<br>

1-1:继承Thread类<br>

1-2:实现Runnable接口<br>

2:线程中的方法比较有特点,比如:启动(start)、休眠(sleep)、停止等,多个线程是交互执行的(CUP在某个时刻

只能执行一个线程,当一个线程休眠了或者执行完毕了,另一个线程才能占用CPU来执行),因为这是CPU的结构来决

定的,在某个时刻CUP只能执行一个线程,不过速度相当快,对于人来讲可以认为是并行执行的。

在一个.java文件中,可以有多个类,但只能有一个public类。

这两种创建线程的方法本身没有什么不同,一个是实现Runnable接口,一个是继承Thread类。而使用实现Runnable接口这种方法:1.可以避免Java的单继承的特性带来的局限性;2.适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码及数据有效分离,较好地体现了面向对象的设计思想。开发中大多情况下都使用实现Runnable接口这种方法创建线程。

实现Runnable接口创建的线程最终还是要通过将自身实例作为参数传递给Thread然后执行

语法:Thread Actress = new Thread(Runnable target, String name)

例如:Thread actressThread=new Thread(new Actress(),"Ms.Runnable");

actressThread.start();

}

}

volatile关键字

    保证了线程可以正确地读取其他线程写入的值,如果不写成volatile,由于可见性的问题,当前线程有可能不能读到这个值。

    可见性JMM(JAVA内存模型)happens-before原则、可见性原则

    用volatile修饰的变量,线程在每次使用该变量的时候,都会读取变量修改后的值

加入join是为了让舞台线程最后停止,如果不加有可能舞台线程结束,军队线程还未停止,就好比导演喊停,演员还在演!可以在join后面加入测试语句System.out.println("舞台结束!");,然后去掉或者保留join观察效果。

Thread.yield();//让出处理器时间,公平竞争

军队线程

public class armyRunnable implements Runnable {

//volatile保证了线程可以正确读取其他线程写入的值

volatile boolean keeprunning=true;

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()+"结束战斗");

}

}

//舞台线程

public class Stage extends Thread {

public void run(){

//创建runnable接口实例

ArmyRunnable armyTaskOfSuiDynasty = new ArmyRunnable();

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;

//舞台线程等待该线程的结束

try {
armyOfRevolt.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

keyperson类

public class Keyperson extends Thread {

public void run(){
System.out.println(getName()+"开始战斗");
for(int i=0;i<10;i++){
System.out.println(getName()+"左突右击,攻击隋军");
}
System.out.println(getName()+"结束战斗");
}

}

join方法会是所有线程等待调用join方法的线程执行完毕

/**

 *隋唐演义大舞台

 */

public class Stage extends Thread {
@Override
public void run() {

System.out.println("正当双方杀得正High,半路杀出了个程咬金!");

Thread mrChen=new KeyPersonThread();
mrChen.setName("程咬金");

//停止军队作战
//停止线程的方法
armyTaskOfSuiDynasty.keepRunning=false;
armyTaskOfRevolt.keepRunning=false;

try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}

/**
* 历史大戏留给关键人物
*/
mrChen.start();

//万众瞩目,所有线程等待程先生完成历史使命
try {
mrChen.join();//对象是mrChen
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}

System.out.println("谢谢观看隋唐演义,再见!");

}

Ps:Thread.currentThread()表示静态意思。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: