看完后,你再也不用怕面试问并发编程啦( 三 )

 查看进程堆栈
使用jstack可查看指定进程(pid)的堆栈信息,用以分析线程执行状态:

  • 进入cmd: Win + R

看完后,你再也不用怕面试问并发编程啦

文章插图
  • 输入jstack 进程号

看完后,你再也不用怕面试问并发编程啦

文章插图
5、多线程编程:join、yield、sleep区别?目标: 学习如何控制线程执行顺序、线程让步、优先级 。
join 作用
  • join()方法【加入线程】 , 把指定的线程加入到当前线程 , 可以将两个交替执行的线程合并为顺序执行的线程 。线程调用了join方法,那么就要一直运行到该线程结束,才会运行其他线程 。这样可以控制线程执行顺序 。
  • join()方法,内部实现使用了 synchronized 会占用锁 。线程结束,锁释放 。
  •  join(long millis)
     – 如果为0表示永远等待,其实是等到线程结束后 。
     – 传入指定的时间会调用wait(millis), 时间到锁释放 , 不再等待 。
yield 作用
  • thread.yield()【线程让步】 让出CPU的时间片尽量切换到其它线程去执行 。
  • 使正在运行中的线程重新变成就绪状态 , 并重新竞争 CPU 的调度权 。它可能会获取到,也有可能被其它线程获取到 。
yield 和 sleep 的异同
  • 优先级:sleep休眠线程后,会给其他线程执行机会,不考虑线程的优先级问题;yield让步后只有优先级高于或等于当前线程的线程才有执行机会 。
  • 状态:sleep当前线程由运行态进入超时等待状态;yield当前线程由运行态到就绪态 。
  • 异常:sleep方法在声明时抛出InterruptedException异常,所以在使用时要么try捕获要么throws抛出;而yield没有声明异常 。
线程优先级
线程的优先级说明该线程在程序中的重要性 。系统会根据优先级决定首先使用哪个线程,但这并不意味着优先级低的线程得不到运行,只是它运行的机率比较小而已 , 比如垃圾回收机制 。
优先级范围1-10,默认为5,比如设置最高优先级为10:
t1.setPriority(Thread.MAX_PRIORITY);
代码:package cn.itcast.thread;/** * join() : 加入线程 * yield() : 线程让步 * sleep() : 线程休眠 */public class Test3 {public static void main(String[] args) throws InterruptedException {// 线程1Thread t1 = new Thread(() -> {for (int i = 1; i <= 20; i++) {System.out.println(Thread.currentThread().getName() + i);// 线程让步//Thread.yield();}},"t1:");// 线程2Thread t2 = new Thread(() -> {for (int i = 1; i <= 20; i++) {System.out.println(Thread.currentThread().getName() + i);}},"t2:");// 启动线程t1.start();// 加入线程t1.join();// 设置线程优先级//t1.setPriority(Thread.MIN_PRIORITY);t2.start();// 设置线程优先级//t2.setPriority(Thread.MIN_PRIORITY);}} 小结
  • join作用?
 加入线程,线程调用了join方法,那么就要一直运行到该线程结束,才会运行其他线程. 这样可以控制线程执行顺序 。
  • yield作用?
 线程让步 , 让出CPU的时间片尽量切换其他线程去执行 。
  • 线程优先级?
     设置线程优先级 , 优先级可以设置1-10 , 数字越大代表优先级越高 。
     在Java语言中 , 每个线程都有一个优先级,当线程调控器有机会选择新的线程时 , 线程的优先级越高越有可能先被选择执行 。6、并发编程需要处理的问题:死锁问题并发编程的目的是为了让程序运行得更快,但是,并不是启动更多的线程就能让程序最大限度地并发执行 。在进行并发编程时,如果希望通过多线程执行任务让程序运行得更快,会面临非常多的挑战,比如死锁的问题、上下文切换的问题 。
描述
锁是个非常有用的工具,运用场景非常多,因为它使用起来非常简单,而且易于理解 。但同时它也会带来一些困扰,那就是可能会引起死锁,一旦产生死锁,就会造成系统功能不可用 。让我们先来看一段代码,这段代码会引起死锁,使线程t1 和 线程t2 互相等待对方释放锁 。
演示
什么是死锁?多线程竞争共享资源,导致线程相互等待,程序无法向下执行 。


推荐阅读