学过创建线程的二种方法,一是继承Thread类,重写run方法,第二种是实现Runnble接口,推荐使用第二种,这样能够避免单继承的局限性。
接下来用第二种实现Runnble接口写下案例,模拟抢票
package com.cb.thread;
/*
* 共享资源,并发(线程安全)
*/
public class Web12306 implements Runnable{
private int ticketNums = 99; //99张票
@Override
public void run() {
while(true){
if(ticketNums<0){
break;
}
try {
Thread.sleep(200);//模拟延时
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Thread.currentThread().getName()谁运行run就是代表谁
System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
}
}
public static void main(String[] args) {
//一份资源
Web12306 web = new Web12306();
System.out.println(Thread.currentThread().getName());
//三个代理
new Thread(web,"码畜").start(); //加上名字,区分线程
new Thread(web,"码农").start();
new Thread(web,"码蟥").start();
}
}
运行结果:
从结果可以看出来数据不正确,就涉及到并发也就是线程安全问题,目前还没学到并发,所以先不解决。
龟免赛跑案例
package com.cb.thread;
/*
* 模拟龟兔赛跑
*/
public class Racer implements Runnable{
private String winner; //胜利者
@Override
public void run() {
for (int steps=0;steps<=100;steps++) {
//模拟兔子休息
if (Thread.currentThread().getName().equals("兔子")&& steps%60==0) {//兔子每走60步休息一次
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"-->"+steps);
//把步数传过去,看比赛是否结束
boolean flag = gameOver(steps);
if(flag){
break;
}
}
System.out.println();
}
private boolean gameOver(int steps){
if (winner!=null) {//存在胜利者
return true;
}else {
if (steps==100) {
winner = Thread.currentThread().getName();
System.out.println("胜利者:"+winner);
return true;
}
}
return false;
}
public static void main(String[] args) {
Racer racer = new Racer();
new Thread(racer,"乌龟").start();
new Thread(racer,"兔子").start();;
}
}