zoukankan      html  css  js  c++  java
  • 多线程编程(2)

     线程自身阻塞

       线程由于某些原因,可以停下一段时间即调用Sleep方法

    妈妈给女儿削梨(Join)

    1.妈妈削梨(thread1)
    2.女儿吃梨(thread2)

    必须先妈妈削梨,然后女儿才可以吃梨.即女儿在等待妈妈削梨这个动作结束,否则的话则停止吃梨.即线程2是依赖于线程1的.如下代码

    此处调用了线程的Join方法,以等待该线程结束

    public class Demo1
    {
        private Thread thread2;
        private Thread thread1;
        public Demo1()
        {
            thread1 = new Thread(new ThreadStart(Task1));
            thread2 = new Thread(new ThreadStart(Task2));
            thread2.Start();
            thread1.Start();
        }
    
        public void Task1()
        {
            Console.WriteLine("削梨");
            Console.WriteLine(DateTime.Now);
            Thread.Sleep(5000);
        }
    
        public void Task2()
        {
            thread1.Join();
            Console.WriteLine(DateTime.Now);
            Console.WriteLine("吃梨");
        }
    }

    结果

    image

    Join有3个重载方法,如果线程1未结束,那么线程2那一直等待,可以设置一个时间,一直没反应的话则继续执行.

    如果两个线程的任务是无关的,那么会运行的很好。一旦有了关系,则复杂度就出来了。

    女儿改变想法不吃梨了(Interrupt)

    如果妈妈削梨需要5分钟,而女儿只愿意等3分钟,3分钟过后就不要吃梨了,怪她娘削的太慢,然后让她娘别削了(做妈的真不容易)…
    即线程2等了3分钟,若线程1还没完成任务,那么线程2就终止了线程1的操作

    示例如下,Interrupt方法会中断处于WaitSleepJoin状态的线程,并抛出ThreadInterruptedException 异常

    public void Task1()
    {
        Console.WriteLine("妈妈开始削梨");
        try
        {
            Thread.Sleep(5000);
        }
        catch (ThreadInterruptedException e)
        {
            Console.WriteLine("妈妈停止削梨");
        }
    }
    
    public void Task2()
    {
        var date1 = DateTime.Now;
        thread1.Join(3000);
        var date2 = DateTime.Now;
        if ((date2 - date1).TotalSeconds >= 3)
        {
            Console.WriteLine("女儿不吃梨了");
            thread1.Interrupt();
        }
        else
        {
            Console.WriteLine("吃梨");
        }
    }

    image

    女儿突然不想吃梨了

    上面的例子是考验耐性,
    即线程在处于WaitSleepJoin的状态下,调用Interrupt来唤醒线程并中断
    但妈妈是一直在削梨的,即这个线程是在做事的,不管梨有没削好,突然女儿就要吃梨了。。。即要将线程给中止掉.
    示例如下
    注意:这里线程2首先自身挂起3秒,跟线程1无关,其也不清楚线程1在干嘛,就是过了3秒突然想中止(Abort方法)线程1的任务
    并非绝对的中止和中断:其是通过抛出异常来捕获中止和中断信息的,而非直接退出

    public void Task1()
    {
        Console.WriteLine("妈妈开始削梨");
        try
        {
            Thread.Sleep(5000);
        }
        catch (ThreadInterruptedException e)
        {
            Console.WriteLine("妈妈中断削梨");
        }
        catch (ThreadAbortException e)
        {
            Console.WriteLine("妈妈中止削梨");
        }
    }
    
    public void Task2()
    {
        Thread.Sleep(3000);
        Console.WriteLine("女儿不吃梨了"); 
    thread1.Abort(); }

    中止以后:
    当妈妈收到中止削梨的信号时,线程本身内部还可以做一些善后处理。比如女儿不吃自己吃微笑

    当线程中止后,如果不调用ResetAbort方法,那么该线程catch之后的代码将无法继续执行.
    如下示例

    public void Task1()
    {
        Console.WriteLine("妈妈开始削梨");
        try
        {
            Thread.Sleep(5000);
        }
        catch (ThreadInterruptedException e)
        {
            Console.WriteLine("妈妈中断削梨");
        }
        catch (ThreadAbortException e)
        {
            Console.WriteLine("妈妈中止削梨");
            Thread.ResetAbort();
        }
        Console.WriteLine("妈妈自己吃");
    }
    

    结果如下

    image

  • 相关阅读:
    (网络编程)基于tcp(粘包问题) udp协议的套接字通信
    (网络编程)理论 原理
    (网络编程) 介绍
    C++开源代码项目汇总
    Facial Landmark Detection
    人脸对齐ASM-AAM-CLM的一些总结
    Ello讲述Haar人脸检测:易懂、很详细、值得围观
    显示形状回归算法(ESR)代码介绍
    百度图像搜索探秘
    人脸特征点检测
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/1878357.html
Copyright © 2011-2022 走看看