慕课学习链接
Thread join 方法 用途 异常join 方法会 throws InterruptedException,所以使用时,要么捕获,要么抛出。
使用创建3个线程,等3个线程都执行完成再进行响应 *** 作。
public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(new Runnable(){ @Override public void run(){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread()+"sleep 1s"); } }); Thread t2 = new Thread(new Runnable(){ @Override public void run(){ try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread()+"sleep 5s"); } }); Thread t3 = new Thread(new Runnable(){ @Override public void run(){ try { Thread.sleep(8000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread()+"sleep 8s"); } }); t1.start(); t2.start(); t3.start(); t1.join(); t2.join(); t3.join(); System.out.println("end"); }
不使用 join 方法,先输出 “end” ,再输出 线程1,2,3的执行。
使用 join 之后,线程执行完成之后才会输出 “end”。有点像异步时设置参数为同步。
有参数的 join 方法join(毫秒数) n毫秒之后不再等待。Thread yield 方法 用途
谦让,在没有用完 CPU 分配的时间时,主动让出 CPU 时间,给其他同优先级的线程使用。
特点static 静态的,Thread.yield() 直接调用。
native 本地,调用非 Java 语言实现的方法, *** 作 *** 作系统。
使用创建一个线程,执行1-10000 的累加,加入 yield 方法,执行速度较慢。
public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(new Runnable(){ @Override public void run(){ int sum = 0; for(int i=0;i<10000000;i++){ sum = sum + i; Thread.yield(); } } }); long cur = System.currentTimeMillis(); t1.start(); t1.join(); System.out.println(System.currentTimeMillis()-cur); }sleep() yield() 区别
sleep() 方法,线程阻塞,允许其他所有线程先执行,会抛出异常,可移植性好。
yield() 方法,线程就绪,只允许优先级相同或更高的线程先执行,不会抛异常。
上下文切换和死锁 上下文切换一个线程 CPU 分配的时间片用完,或者被中断,进入就绪状态,需要保存执行到的状态,让出 CPU 给其他线程执行,这就是上下文切换。
线程死锁:两个或两个以上的线程,因争夺资源互相等待,没有外力的作用下,会一直等待下去。
死锁的必要条件互斥:一个资源一段时间只能被同一个进程占用
不可剥夺:不能被强制终止。
请求与保持:占有一个资源,请求另一个资源
循环等待
死锁实现public static void main(String[] args) throws InterruptedException { Object a = 1; Object b = 2; Thread t1 = new Thread(new Runnable(){ @Override public void run(){ synchronized (a){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("1 -> b" ); synchronized (b){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println("end" ); } }); Thread t2 = new Thread(new Runnable(){ @Override public void run(){ synchronized (b){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("2 -> a" ); synchronized (a){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println("end" ); } }); t1.start(); t2.start(); }破坏必要条件,避免死锁
只有请求保持和循环等待可以破坏,以上,通过调整获取资源的顺序,都是 先获取a,再获取b,避免循环等待,可以避免死锁。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)