欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

J2SE(9)之多线程(线程的状态、join、yield、sleep)

程序员文章站 2022-05-12 14:53:31
...

1、线程的状态

Java中的线程的生命周期大体可分为5种状态。

1. 新建(NEW):新创建了一个线程对象:new Thread(new Runnable实现类)。

2. 可运行(RUNNABLE):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。

3. 运行(RUNNING):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。
4. 阻塞(BLOCKED):阻塞状态是指线程因为某种原因放弃了cpu 使用权,即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分三种:

(一). 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。
(二). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
(三). 其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。

5. 死亡(DEAD):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

J2SE(9)之多线程(线程的状态、join、yield、sleep)

参考地址:https://blog.csdn.net/xingjing1226/article/details/81977129

1.1 如何干涉线程的状态以及停止方法

public class StopDemo01 {
	public static void main(String[] args) {
		Study s =new Study();
		new Thread(s).start();
		
		//外部干涉
		for(int i=0;i<100;i++){
			if(50==i){ //外部干涉
				s.stop();
			}
			System.out.println("main.....-->"+i);
		}
	}
}
class Study implements Runnable{
	 //1)、线程类中 定义 线程体使用的标识	 
	private boolean flag =true;
	@Override
	public void run() {
		//2)、线程体使用该标识
		while(flag){
			System.out.println("study thread....");
		}
	}
	//3)、对外提供方法改变标识
	public void stop(){
		this.flag =false;
	}	
}

2、线程的合并,阻塞

1join :合并线程,调用join方法的线程对象加入到线程队列中,变成单线程了。
2yield:暂停自己的线程,是static方法。在哪个线程的主体中调用,就是暂停哪个线程。

2.1 join方法

/**
 * join:合并线程
 */
public class JoinDemo01 extends Thread {
	public static void main(String[] args) throws InterruptedException {
		JoinDemo01 demo = new JoinDemo01();
		Thread t = new Thread(demo); //新生
		t.start();//就绪
		//cpu调度 运行
			
		for(int i=0;i<1000;i++){
			if(50==i){
				t.join(); //把t线程对象加入到main线程,main会阻塞...会先执行完t,才会再次执行main
			}
			System.out.println("main...."+i);
		}
	}
	
	@Override
	public void run() {
		for(int i=0;i<1000;i++){
			System.out.println("join...."+i);
		}
	}
}

2.2 yield方法

public class YieldDemo01 extends Thread {
	public static void main(String[] args) {
		YieldDemo01 demo = new YieldDemo01();
		Thread t = new Thread(demo); //新生
		t.start();//就绪
		//cpu调度 运行
		
		for(int i=0;i<1000;i++){
			if(i%20==0){
				//暂停本线程 main
				Thread.yield();
			}
			System.out.println("main...."+i);
		}
	}
	
	@Override
	public void run() {
		for(int i=0;i<1000;i++){
			System.out.println("yield...."+i);
		}
	}
}

 

3、sleep方法

sleep方法不会释放锁对象。

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 倒计时
 * 1、倒数10个数,一秒内打印一个
 * 2、倒计时
 */
public class SleepDemo01 {

	public static void main(String[] args) throws InterruptedException {
		Date endTime =new Date(System.currentTimeMillis()+10*1000);
		long end =endTime.getTime();
		while(true){
			//输出
			System.out.println(new SimpleDateFormat("mm:ss").format(endTime));
			//等待一秒
			Thread.sleep(1000);
			//构建下一秒时间
			endTime =new Date(endTime.getTime()-1000);
			//10秒以内 继续 否则 退出
			if(end-10000>endTime.getTime()){
				break;
			}
		}	
	}
	public static void test1() throws InterruptedException{
		int num =10;
		while(true){
			System.out.println(num--);
			Thread.sleep(1000); //暂停
			if(num<=0){
				break;
			}
		}
	}	
}

sleep模拟 网络延时  线程不安全的类

/**
 * Sleep模拟 网络延时  线程不安全的类
 */
public class SleepDemo02 {
	public static void main(String[] args) {
		//真实角色
		Web12306 web= new Web12306();
		Web12306 web2 = new Web12306();
		//代理
		Thread t1 =new Thread(web,"路人甲");
		Thread t2 =new Thread(web,"黄牛已");
		Thread t3 =new Thread(web,"攻城师");
		//启动线程
		t1.start();
		t2.start();
		t3.start();
	}
}

class Web12306 implements Runnable {
	private int num =50;

	@Override
	public void run() {
		while(true){
			if(num<=0){
				break; //跳出循环
			}
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
		}
	}
}

4、线程的基本信息

public class MyThread implements Runnable {
	private boolean flag =true;
	private int num =0;
	@Override
	public void run() {
		while(flag){
			System.out.println(Thread.currentThread().getName()+"-->"+num++);
		}
	}
	public void stop(){
		this.flag=!this.flag;
	}
}
/**
  Thread.currentThread()	 :当前线程
  setName():设置名称
  getName():获取名称
  isAlive():判断状态
 */
public class InfoDemo01 {

	public static void main(String[] args) throws InterruptedException {
		MyThread it =new MyThread();
		Thread proxy =new Thread(it,"挨踢");
		proxy.setName("test");
		System.out.println(proxy.getName());
		System.out.println(Thread.currentThread().getName()); //main
		
		proxy.start();
		System.out.println("启动后的状态:"+proxy.isAlive());
		Thread.sleep(200);
		it.stop();
		Thread.sleep(100);
		System.out.println("停止后的状态:"+proxy.isAlive());
	}
}

线程的优级别:

    优先级代表的概率,不是绝对的先后顺序:

/**
 * 优先级:概率,不是绝对的先后顺序
   MAX_PRIORITY  10
   NORM_PRIORITY 5 (默认)
   MIN_PRIORITY  1
   
   setPriority()
   getPriority()
 */
public class InfoDemo02 {

	public static void main(String[] args) throws InterruptedException {
		MyThread it =new MyThread();
		Thread p1 =new Thread(it,"挨踢1");
		MyThread it2 =new MyThread();
		Thread p2 =new Thread(it2,"挨踢2");
		
		p1.setPriority(Thread.MIN_PRIORITY); //设置优先级
		p2.setPriority(Thread.MAX_PRIORITY);//设置优先级
		p1.start();
		p2.start();
			
		Thread.sleep(100);
		it.stop();
		it2.stop();
	}
}

 

相关标签: J2SE