java初入多线程4

线程中断

  1. 概念 :让目标线程停止执行,但是是高知目标线程希望线退出,具体退出由目标线程自己决定。
  2. 相关的方法,暂时只介绍Thread的方法
  • Thread.interrupt() //中断线程 也是告知目标线程中断,也就是设置中断标志位
  • Thread.isInterrupted() //判断是否被中断--通过上面方法设置的中断标志位来判断是否被中断
  • Thread.interrupted //判断是否被中断,并清楚中断状态,,, 用来判断当前线程的中断状态,同事清除中断标志位状态
  1. 程序实现
public static void main(String[] args) throws InterruptedException {
        Thread t1=new Thread(){
            @Override
            public void run() {
                while(true){
                    //在这里判断 是否有中断位  ,又中断位了就将线程终止
                    if(Thread.currentThread().isInterrupted()){
                        System.out.println("中断了");
                        break;
                        
                    }
                    
                    Thread.yield();
                }
            }
        };
        t1.start();
        Thread.sleep(2000);
        t1.interrupt();  // 在这里进行通知中断
    }

通知(notity)与等待(wait)

  1. 当一个线程执行wait方法的时候,那么当前线程就会停止继续执行,转为等待的状态,然后等其他线程执行notity 方法为止。执行如图所示,如果用notity是随机唤醒一个线程不是按照执行顺序唤醒线程
java初入多线程4_第1张图片
notity唤醒等待的线程
java初入多线程4_第2张图片
wait和notity的工作流程

wait 执行后会释放对应的监视器,其他线程会获得该监视器,然后执行notity 之后 会释放监视器,wait 重新获得监视器,继续执行程序。

public class SimpleWN {
    
    final static Object object =new Object();
    
    public static class T1 extends Thread{
        @Override
        public void run() {
            
            synchronized(object) {
                System.out.println(System.currentTimeMillis()+ "T1 start!");
                try {
                    System.out.println(System.currentTimeMillis() + "T1 wait for object");
                    object.wait();   //wait等待 然后等到notity来唤醒 ,但是notity唤醒也是随机的  并且wait 方法会释放目标对象的锁而下面的sleep方法就不会释放
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println(System.currentTimeMillis() + ": T1 end!");
            }
            
        }
    }
    
    public static class T2 extends Thread{
        @Override
        public void run() {
            synchronized (object) {
                System.out.println(System.currentTimeMillis()+"T2 start ! notity one thread");
                object.notify();
                System.out.println(System.currentTimeMillis()+"T2 end!");
                try {
                    Thread.sleep(2000);  //睡眠2秒
                } catch (Exception e) {
                    // TODO: handle exception
                }
            }
            
        }
    }
    public static void main(String[] args) {
        Thread thread1=new T1();
        Thread thread2=new T2();
        thread1.start();
        thread2.start();
    }

}

挂起(suspend)和继续执行(resume)

  1. 被废弃的方法,说明下原理:suspend 在导致线程暂停的通识不把锁的资源释放,其他线程 如果访问没有被释放的锁,那么也会受到牵连导致无法 继续执行。除非在该暂停的线程上进行了resume操作那么该线程才会继续执行,阻塞的其他线程也会继续执行。如果resume 操作在suspend前执行了那么被执行suspend的线程很难有机会再被继续执行。这种情况下很可能出现死锁的情况
java初入多线程4_第3张图片
死锁

等待线程结束(join)和谦让(yield)

  1. 我们在程序的执行中,很可能会出现多个线程之间有依赖关系的线程,只有当前一个线程执行完毕后才能继续执行以后的线程,那么我们可以使用join方法来实现 ,等待线程结束。看如下代码
public class JoinMain {

    /**
     * volatile  变量的可见性 不可代替锁
     */
    private volatile static int i=0;
    
    public static class AddThread extends Thread{
        @Override
        public void run() {
            for(i=0;i<10000000;i++);
        }
    }
    
    public static void main(String[] args) throws Exception {
        AddThread thread= new AddThread();
        thread.start();
        thread.join(); //等待的意思  本质是让调用线程wait 在当前线程实例上 调用的是wait(0) 这个方法
        System.out.println(i);
    }
    
}

代码执行结果如图

java初入多线程4_第4张图片
运行结果
java初入多线程4_第5张图片
注释掉join

从上面两个图可以看出来 如果不适用join 那么执行的结果会很小。执行join方法后会让该线程等待addThread线程执行完毕。

  1. yield方法:谦让,谦让,意思 当该方法执行后会让当前线程把cpu 让出来,到那时有一点需要注意的是让出cpu后该线程还会参与到cpu的争夺中,会不会分配到 这就不一定了。

你可能感兴趣的:(java初入多线程4)