多线程与高并发—3.线程进入状态的三种最基本方法

首先我们来认识一下线程进入状态的三种最基本方法。

第一个方法呢,叫Sleep方法。Sleep就是睡眠,所谓睡眠的意思就是当前线程暂停一段时间,让给别的线程去运行。这个线程睡眠让给别的线程到底是什么概念?如果从操作系统的角度来讲的话,在CPU中,对于CPU来说,它是没有线程这个概念,它只知道从内存里面把指令拿过来运行,再拿下一条指令运行,再再拿下一条指令运行。一直就这么不停的循环,不停的循环,直到没有指令了,就歇着。所以其实对cpu来说没有线程这个概念

多线程是什么意思?其实,就是有好多不同的线程,如果只有一个cpu的话,那么每个线程呢就在CPU上执行一会儿,执行一会儿之后就把你扔出去,再把第二个线程再拿进来,然后执行一会儿之后就把你扔出去,再把第三个线程拿进来,就这么一个概念。

代码部分:

import javax.sql.rowset.Joinable;

public class T03_Sleep_Yield_Join {
	
	public static void main(String[] args) {
		//testSleep();
		//testYield();
		testJoin();
			
	}
	
	static void testSleep() {
		new Thread(()->{
			for(int i=0;i<10;i++) {
				System.out.println("A"+i);
				try {
					Thread.sleep(1000);
					 //跟上面是一样的,都是毫秒
					//TimeUnitMillliseconds.sleep(500) 
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}).start();
	}
	
	static void testYield() {
		new Thread(()->{
			for(int i=0;i<50;i++) {
				System.out.println("A"+i);
				if(i%10==0) Thread.yield();
			}
		}).start();
	    new Thread(()->{
	    	for(int i=0;i<50;i++) {
	    		System.out.println("----------B"+i);
	    		if(i%10==0) Thread.yield();
	    	}
	    }).start();
	}
	
	static void testJoin() {		
		Thread t1 = new Thread(()->{
			for(int i=0;i<10;i++) {
				System.out.println("A"+i);
				try {
					Thread.sleep(50);
					
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
		
		Thread t2 = new Thread(()->{
			System.out.println("运行1");      
			  try {   t1.start();
			    	  t1.join();
					System.out.println("运行2");
					
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			       System.out.println("运行3");
		});	
		t2.start();
		
	}
	

}

sleep是什么意思呢?就是说这个线程,让你在这里睡个500个毫秒,然后这500毫秒之内,别的线程可以去运行,让给别的线程去运行。

Sleep代码测试结果如下:

A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
每隔500毫秒出来一个

第二个叫Yield方法,Yield是什么意思呢?然后我一个线程在运行,另外一个线程也在运行,然后,当前这个线程在cpu上运行,运行到某个地方的时候,它调了个Yield的方法,意思是,当前线程先退出一下,从cpu上先离开,离开之后,别的线程是有机会在这执行的。当然,当前离开了之后,如果说别的线程没执行,当前线程还可能继续回来继续执行。所谓的离开就是当前线程进入到一个等待队列里面,回到等待队列里,在操作系统的这个调度算法里,还是依然有可能把当前调回去的线程再拿回来执行,当然,更大的可能性是把原来等待那些线程拿出一个来执行,所谓Yield的本质上就是我让出一下cpu,返回到就绪状态。

Yield代码测试结果如下:

A0
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
----------B0
A11
A12
A13
A14
A15
A16
A17
A18
A19
A20
----------B1
----------B2
A21
A22
A23
A24
A25
A26
A27
----------B3
----------B4
----------B5
----------B6
----------B7
----------B8
----------B9
----------B10
----------B11
----------B12
A28
----------B13
----------B14
----------B15
A29
A30
----------B16
----------B17
----------B18
A31
----------B19
A32
----------B20
----------B21
----------B22
----------B23
----------B24
----------B25
----------B26
----------B27
----------B28
----------B29
----------B30
A33
A34
A35
A36
A37
A38
A39
A40
----------B31
----------B32
A41
A42
A43
A44
A45
A46
A47
A48
A49
----------B33
----------B34
----------B35
----------B36
----------B37
----------B38
----------B39
----------B40
----------B41
----------B42
----------B43
----------B44
----------B45
----------B46
----------B47
----------B48
----------B49
逢10必让

第三个叫Join方法,join的意思是如果我们有第一个线程叫T1,第二个线程叫T2,它调用过程中,如果是在T1的某个地方,调了T1.Join。如果在T1线程里调T.Join是没有任何意义的,如果是调了T2.Join,Join的意思叫加入,意思就是CPU现在运行T2,T1就在这等着,什么时候T2运行完了T1继续运行,Join经常用来等待另外一个线程的结束。

以前有个面试题:我怎么才能保证三个线程能够按顺序执行完?你在那个主线程里,先调用T1.Jion再调T2.Jion,再调T3.Jion就可以了。还有一种那个更加精确的方式呢,就是你T1里面的T2.Jion,T2里面调T3.Jion。

Jion代码测试结果如下:

运行1
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
运行2
运行3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值