一个月精通Java并发编程

3.5常见方法

方法名static功能说明注意
start()启动一个新线程,在新的线程运行run方法中的代码start 方法只能是让线程进入就绪,里面的代码不一定立刻运行(CPU的时间片还没有分给它),每个线程对象的start方法只能调用一次,如果调用多次会出现IlleagleThreadStateException
run()新线程启动后会调用的方法如果在构造Thread对象时传递了Runnable参数,则线程启动后会调用Runnable中的run方法,否则默认不执行任何操作.但是可以创建Thread的子类对象,来覆盖默认行为
join()等待线程运行结束
join(long n)等待线程运行结束,最多等待n毫秒
getId()获取线程长整型的id唯一id唯一
getName()获取线程名
setName()修改线程名
getPriority()获取线程优先级
setPriority()修改线程优先级Java中规定线程的优先级是1~10的整数,较大的优先级能提高该线程被CPU调度的几率
getState()获取线程状态Java中线程状态是用6个enum表示,分别为NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED
isInterrupted()判断是否被打断不会清楚打断标记
isAlive()线程是否存活(还没有运行完毕)
interrupt()打断线程如果被打断线程正在sleep,wait,join会导致被打断的线程抛出InterruptedException,并清除打断标记,如果打断的正在运行的线程,则会设置打断标志,park的线程被打断,也会设置打断标记
interrupted()static判断当前线程是否被打断会清除 打断标记
currentThread()static获取当前正在执行的线程
sleep(long n)static让当前执行的线程休眠n毫秒,休眠时让出CPU的时间片给其他线程
yield()static提示线程调度器让出当前线程对CPU的使用主要是为了测试和调试

3.6 start与run

Java的线程是通过java.lang.Thread类来实现的。VM启动时会有一个由主方法所定义的线程。可以通过创建Thread的实例来创建新的线程。每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体。通过调用Thread类的start()方法来启动一个线程。

3.7 sleep与yield

sleep
1.调用sleep会让当前线程从Running进入Timed Waiting状态
2.其他线程可以使用interrupt方法打断正在睡眠的线程,这时sleep方法会抛出InterruptedException
3.睡眠结束后的线程未必会立刻得到执行
4.建议使用TimeUtil的sleep替代Thread的sleep来获得更好的可读性.

yield
1.调用yield会让当前线程从Running 进入 Runnable状态,然后调度执行其他同优先级的线程.如果这时没有同优先级的线程,那么不能保证让当前线程暂停的效果
2.具体的实现依赖于操作系统的任务调度器

线程优先级

  • 线程优先级会提示调度器优先调度该线程,但是它仅仅是一个提示,调度器可以忽略它
  • 如果CPU比较忙,那么优先级高的线程会获得更多的时间片,但CPU闲时,优先级几乎没有作用

案例-防止CPU占用率100%
Sleep实现
在没有利用CPU来计算时,不要让while(true)空转浪费CPU,这时可以使用yield或者sleep来让出cpu的使用权给其他程序

    while(true){
		try{
		Thread.sleep(50);
	}catch (InterruptedException e) {
			e.printStackTrace();
	}
}
  • 可以用wait或者条件变量达到类似的效果
  • 不同的是,后两种都需要加锁,并且需要相应的唤醒操作,一般适用于需要进行同步的场景
  • sleep适用于无需锁同步的场景

wait实现
synchronized(锁对象) {
while(条件不满足 )
}

3.8 Join方法详解

	public class Test10 {
		static int r =0;
		public static void main(String[] args) throws InterruputedException {
		test1();
	}

	private static void test1() throws InterruptedException {
		log.debug("开始");
		Thread t1 = new Thread(()->{
			log.debug("开始");
			sleep(1);
			log.debug("结束");
			r = 10;
		},"t1");
	}
    t1.start();
	log.debug("结果为:{}",r);
	log.debug("结果")	}

分析:

  • 因为主线程和线程t1是并行执行的,t1需要1秒之后才能算出r =10;
  • 而主线程一开始就要打印r的结果,所以只能打印出r=0

解决方法

  • 用sleep行不行?为什么?
  • 用join ,加在t1.start()之后即可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值