Java多线程的创建和状态信息乐字节

37次阅读

共计 4019 个字符,预计需要花费 11 分钟才能阅读完成。

大家好,我是乐字节的小乐,好看好学的 Java 干货又来了!上一篇我们说到了 Java 多线程的概念以及优缺点,本文将接着说 Java 多线程的创建,以及多线程的状态。

一、创建线程

1、创建 Thread 的子类

创建: 继承 Thread + 重写 run

启动: 创建子类对象 对象.start()

创建 Thread 子类的一个实例并重写 run 方法,run 方法会在调用 start() 方法之后被执行,示例如下:

public class MyThread extends Thread {public void run(){for(int i=0;i<10;i++){ 
try {Thread.sleep(20); // 模拟延时
} catch (InterruptedException e) {e.printStackTrace(); 
} 
System.out.println("一边学习多线程");
} 
} 
public static void main(String[] args) {
// 创建子类对象
MyThread myThread = new MyThread();
// 启动线程
myThread.start();
// 也可以创建匿名子类
Thread thread = new Thread(){public void run(){for(int i=0;i<10;i++){ 
try {Thread.sleep(20);// 模拟延时
} catch (InterruptedException e) {e.printStackTrace();
} 
System.out.println("一边玩 QQ"); 
} 
} 
}; 
thread.start(); 
for(int i=0;i<10;i++){ 
try {Thread.sleep(20); // 模拟延时
} catch (InterruptedException e) {e.printStackTrace(); 
} 
System.out.println("一边玩微信..."); 
} 
}
}

2、实现 Runnable 接口 (推荐)

面向接口编程,避免单继承局限

创建: 实现 Runnable + 重写 run

启动: 静态代理 Thread

a)、创建真实角色 实现类对象
b)、创建代理角色 Thread 对象 + 真实角色的引用
c)、代理角色.start()
此方式是新建一个实现了 java.lang.Runnable 接口的类的实例,实例中的方法可以被

线程调用。

缺点: 根据重写规则,run 方法不能对外声明异常,不能有返回值

public class MyRunnable implements Runnable {public void run(){for(int i=0;i<10;i++){ 
try {Thread.sleep(20); // 模拟延时 
} catch (InterruptedException e) {e.printStackTrace(); 
} 
System.out.println("一边学习多线程"); 
} 
} 
public static void main(String[] args) { 
// 使用代理创建线程 
Thread thread = new Thread(new MyRunnable()); 
// 启动线程 
thread.start(); 
// 也可以创建一个实现了 Runnable 接口的匿名类 
Runnable myRunnable = new Runnable(){public void run(){for(int i=0;i<10;i++){ 
try {Thread.sleep(20);// 模拟延时 
} catch (InterruptedException e) {e.printStackTrace(); 
} 
System.out.println("一边玩 QQ"); 
 
} 
} 
}; 
Thread t = new Thread(myRunnable); 
t.start(); 
for(int i=0;i<10;i++){ 
try {Thread.sleep(20); // 模拟延时 
} catch (InterruptedException e) {e.printStackTrace(); 
} 
System.out.println("一边玩微信..."); 
} 
} 
} 

优点: 能声明异常,能有返回值 缺点: 编写复杂麻烦

public class Call {public static void main(String[] args) throws InterruptedException, ExecutionException { 
// 创建线程 
ExecutorService ser=Executors.newFixedThreadPool(2); 
Race tortoise = new Race("老不死",1000); 
Race rabbit = new Race("小兔子",500); 
// 获取值 
Future<Integer> result1 =ser.submit(tortoise) ; 
Future<Integer> result2 =ser.submit(rabbit) ; 
Thread.sleep(2000); // 2 秒 
tortoise.setFlag(false); // 停止线程体循环 
rabbit.setFlag(false); 
int num1 =result1.get(); 
int num2 =result2.get(); 
System.out.println("乌龟跑了 -->"+num1+"步"); 
System.out.println("小兔子跑了 -->"+num2+"步"); 
// 停止服务 
ser.shutdownNow();} 
} 
class Race implements Callable<Integer>{ 
private String name ; // 名称 
private long time; // 延时时间 
private boolean flag =true; 
private int step =0; // 步 
public Race() {} 
public Race(String name) {super(); 
this.name = name; 
} 
public Race(String name,long time) {super(); 
this.name = name; 
this.time =time; 
} 
@Override 
public Integer call() throws Exception {while(flag){Thread.sleep(time); // 延时 
step++; 
} 
return step; 
} 
public String getName() {return name;} 
public void setName(String name) {this.name = name;} 
public long getTime() {return time;} 
public void setTime(long time) {this.time = time;} 
public boolean isFlag() {return flag;} 
public void setFlag(boolean flag) {this.flag = flag;} 
public int getStep() {return step;} 
public void setStep(int step) {this.step = step;} 
} 

二、线程的状态及信息

1、五种状态

1)、新生状态: new
2)、就绪状态: runnable
3)、运行状态: running
4)、阻塞状态: blocked
5)、执行完毕: dead

类似于运动员赛跑,

1)、新生状态: 选出运动员
2)、就绪状态: 走到起跑线,做好跑的动作,枪响后,不是马上就跑,得有反应时间。
3)、运行状态: 反应完成后,开始跑
4)、阻塞状态: 路边一个石头绊倒了,马上跑起来,嘟囔几句,踢踢石头,不是马上跑,重新反应进入就 绪。
5)、终止状态: 跑完了,结束了,慢慢的走几步停下来。

2、阻塞: sleep

模拟网络延时, 每个对象 都有一把排他锁,不会释放锁

class Web12306 implements Runnable { 
private int tickets =20; // 假设 20 张票 
private boolean flag =true; 
@Override 
public void run() {while(flag){if(tickets>=0){ 
try { 
// 模拟延时 
Thread.sleep(200); 
} catch (InterruptedException e) {e.printStackTrace(); 
} 
System.out.println(Thread.currentThread().getName()+"--> 抢票"+tickets--); 
}else{flag =false;} 
} 
} 
public static void main(String[] args) { 
// 真实角色 目标 
Runnable target =new Web12306(); 
// 代理角色 Thread + 真实角色的引用 
Thread proxy1 =new Thread(target,"黄牛 A"); 
Thread proxy2 =new Thread(target,"路人甲"); 
// 代理行为 
proxy1.start(); // 启动线程 
proxy2.start(); // 线程不安全,数据有问题} 
}

3、终止

不要调用 stop destory 方法 , 太暴力,一盆冷水让其停止。

a、正常执行完毕,循环 次数已经到达

b、外部干涉

1)、线程中加入标识 –> 属性
2)、线程体中 使用改标识 –> 死循环
3)、对外提供改变改标识的方法 setXxx() terminate() a()…
4)、外部根据适当的时机调用该方法

4、当前线程

Thread.currentThread()

5、优先级

只代表概率,不代表绝对先后顺序

MIN_PRIORITY:1

NORM_PRIORITY :5 默认优先级

MAX_PRIORITY:10

getPriority() setPriority()

关于多线程的创建和状态就介绍到这里,下次我们再说多线程的同步和线程通信,请关注乐字节,原创文章,转载请注明出处。

正文完
 0