美文网首页
线程间交互问题

线程间交互问题

作者: 向上_d821 | 来源:发表于2019-09-26 16:15 被阅读0次

    问题一:

     try {
         Thread.sleep(500);
     } catch (InterruptedException e) {
         e.printStackTrace();
     }
    

    调用Thread.sleep(500)方法会要捕获异常,那在什么情况下会出现异常呢?

    Thread thread = new Thread(){
                @Override
                public void run() {
                    for(int i=0;i<200000;i++){
                        Log.d("thread--","name: "+i);
                    }
                }
            };
          thread.start();
        }
    

    这是一个线程,循坏打印log。 在上诉代码加上几行

     Thread thread = new Thread(){
                @Override
                public void run() {
                    for(int i=0;i<200000;i++){
                        if(Thread.interrupted()){//这个方法会接收到中断指令,为true,跳出循坏,然后接着它会重置状态值为false
                            return;
                        }
                        try {
                            //线程休息2000毫秒
                            //但是主线程中睡500毫秒之后发出中断指令interrupt,此时子线程还在睡眠中,
                            // 就会走InterruptedException,这个不算异常,这里可以理解为Exception为意外
                            Thread.sleep(2000);
                        } catch (InterruptedException e) { 
                            //走这里的时候,会操作跟Thread.interrupted()一样,重置状态值为false,
                            // 此时上面的Thread.interrupted()为false
                            e.printStackTrace();
                        }
                        Log.d("thread--","name: "+i);
                    }
                }
            };
          thread.start();
          //睡500毫秒
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //500毫秒后发出中断指令
            thread.interrupt();
        }
    

    打印结果

    09-22 19:01:43.267 8194-8278/com.example.threadinteraction D/thread--: name: 0
    09-22 19:01:45.268 8194-8278/com.example.threadinteraction D/thread--: name: 1
    09-22 19:01:47.268 8194-8278/com.example.threadinteraction D/thread--: name: 2
    09-22 19:01:49.269 8194-8278/com.example.threadinteraction D/thread--: name: 3
    09-22 19:01:51.270 8194-8278/com.example.threadinteraction D/thread--: name: 4
    09-22 19:01:53.270 8194-8278/com.example.threadinteraction D/thread--: name: 5
    09-22 19:01:55.271 8194-8278/com.example.threadinteraction D/thread--: name: 6
    ................................
    

    总之:

    当你使用Thread.sleep(2000)中;使得你的线程在睡眠过程中,但是当你用 thread.interrupt(),告诉还在睡眠的线程,此时会走catch(InterruptedException e)
    但是这里不能叫做异常,应该叫做意外,程序会接着执行。具体什么操作,上面代码有注释

    问题二:

    wait和notifyAll的使用

    先看一段代码

     private String content;
       private  synchronized void init(){
           content="线程间互动";
       }
        private synchronized void print(){
          Log.d("打印--","String: "+content);
        }
        public void onClickView(View view) {
           Thread thread1=new Thread(){
               @Override
               public void run() {
                   try {
                       Thread.sleep(500);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                   print();
               }
           };
            thread1.start();
            Thread thread2=new Thread(){
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    init();
                }
            };
            thread2.start();
    

    打印log结果

    09-22 22:10:36.335 10388-10476/com.example.threadinteraction D/打印--: String: null
    

    很明显由于打印数据的时候,还没有初始化数据,导致content值为null

    解决方法:wait和notifyAll的使用
    private  synchronized void init(){
           content="线程间互动";
           //初始化完成之后,唤醒所有之前在等待需要唤醒的线程
           notifyAll();
       }
        private synchronized void print(){
           while (content==null){
               try {
                   //当content值为null的时候,开始等待唤醒
                   wait();
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
          Log.d("打印--","String: "+content);
        }
    
    注意:wait和notifyAll必须在synchronized锁下的方法里,不然运行会报错。wait和notifyAll是Object里的方法

    结果:

    09-22 22:17:22.353 10768-10832/com.example.threadinteraction D/打印--: String: 线程间互动
    

    问题三:

    Thread的join和yield方法

    join当在某个程序执行流中调用其他线程的join()方法,调用的线程将被阻塞,直到被join()加入的join 线程执行完成。

    Thread thread2=new Thread(){
                @Override
                public void run() {
                    //1.此处有很多代码。。。。。。
                    try {
                        thread1.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } 
                    //2.此处有很多代码。。。。。。
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    init();
                }
            };
            thread2.start();
    

    在Thread2中插入一行 thread1.join();在1处和2处之间。代表thread2希望通过thread1.join()方法能够让代码走完1处后,thread2此时相当于wait,等待thread1线程走完之后,自动notify,才接着走一下2处的代码。

    yield:

    当某个线程调用了 yield() 方法暂停之后,只有优先级与当前线程相同,或者优先级比当前线程更高的处于就绪状态的线程才会获得执行的机会。 假如 有线程a、b、c。优先级一样的。 目前执行顺序是c先执行,然后b,最后a,此时c调用了yeild后,c就会在a、b之最后面,或者在a、b之间,不会排在最前面执行了

    相关文章

      网友评论

          本文标题:线程间交互问题

          本文链接:https://www.haomeiwen.com/subject/sghnuctx.html