• .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法


    .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法

    1.多线程简单使用
    (1)进程是不执行代码的,执行代码的是线程,一个进程默认有一个线程
    (2)线程默认情况下都是前台线程,要所有的前台线程退出以后程序才会退出,进程里默认的线程我们叫做主线程或者叫做UI线程
    (3)线程什么时候结束?如果线程是前台线程,该线程执行的方法执行完以后线程就会自动退出
    (4)后台线程只要所有的前台线程结束,后台线程就会立即结束
    (5)多个线程访问同一资源,可能造成不同步的情况,这个叫做线程重入,可以使用lock加锁将执行的共同方法中的代码加上lock
    (6)thread.Abort();//强行停止线程
    Thread.Sleep(5000);//将当前线程暂停5秒
    Thread th = Thread.CurrentThread;//获得当前运行代码的线程
    th.Name="线程名字"
    (7)简单使用
    //创建一个线程对象,并为这个线程对象指定要执行的方法
    Thread thread = new Thread(Test);
    //设置线程为后台线程
    thread.IsBackground = true;
    //开启线程
    thread.Start();
    private void Test()
    {
    Console.Write("多线程测试方法");
    }
    线程调用带参数的方法
    static void ParameterizedThread(object obj)
    {
    Console.WriteLine(obj.ToString());
    }
    ParameterizedThreadStart pts = new ParameterizedThreadStart(ParameterizedThread);
    Thread t = new Thread(pts);
    t.IsBackground = true;
    t.Start("我是带参数的线程");
    (8)lock的本质就是调用以下代码
    private static readonly object obj = new object(); 
    bool isGetLocker = false;
    try

    Monitor.Enter(obj,ref isGetLocker);//获取指定对象上的排它锁,可获取一个值,指示是否获取了该锁
    //尝试获取锁,如果获取成功,isGetLocker=true
    }
    catch(Exception ex)
    {
    throw ex;
    }
    finally
    {
    if(isGetLocker)
    {
    Monitor.Exit(obj);//释放对象上的排它锁
    }
    }
    2.线程死锁
    static object locker1 = new object();
    static object locker2 = new object();

    public static void MainThread()
    {
    new Thread(() =>
    {
    lock (locker1) //获取锁locker1
    {
    Thread.Sleep(1000);
    lock (locker2) //尝试获取locker2
    {
    Console.WriteLine("locker1,locker2");
    }
    }
    }).Start();
    new Thread(() =>
    {
    lock (locker2) //获取锁locker2
    {
    Thread.Sleep(1000);
    lock (locker1) //尝试获取locker1
    {
    Console.WriteLine("locker2,locker1");
    }
    }
    }).Start();
    }

    3.线程通信 生产者消费者模式
    所谓生产者消费者模式就是生产一个对象,然后在消费一个对象,线程通信主要是通过Monitor这个类来进行通信的
    public class Dog
    {
    public static object objLock = new object();
    public string name;
    public string gender;
    }

    public class Factory
    {

    private Dog myDog;
    public Factory(Dog d)
    {
    myDog = d;
    }
    public void Change()
    {
    int i = 0;
    while (true)
    {
    lock (Dog.objLock)
    {
    if (i == 0)
    {
    myDog.name = "ruiky";
    myDog.gender = "Male";
    }
    else
    {
    myDog.name = "瑞奇";
    myDog.gender = "Female";
    }
    i = (i + 1) % 2;
    Monitor.Pulse(Dog.objLock);//通知等待队列中的线程锁定对象状态的更改,激活等待队列中
    //和锁相关的线程
    Monitor.Wait(Dog.objLock);//释放对象上的锁并阻止当前线程,直到它重新获取该锁
    }
    }
    }
    }

    public class Customer
    {
    private Dog myDog;
    public Customer(Dog d)
    {
    myDog = d;
    }
    public void Buy()
    {
    while (true)
    {
    lock (Dog.objLock)
    {
    Console.WriteLine(myDog.name + " , " + myDog.gender);
    Monitor.Pulse(Dog.objLock);
    Monitor.Wait(Dog.objLock);
    }
    }
    }
    }
    //------------------------------
    public static void Main(string[] ar)
    {
    Dog d = new Dog();
    Factory f = new Factory(d);
    Thread thrF = new Thread(f.Change);
    thrF.IsBackground = true;
    Customer c = new Customer(d);
    Thread thrC = new Thread(c.Buy);
    thrC.IsBackground = true;

    thrF.Start();
    thrC.Start();
    Console.ReadLine();
    thrC.Abort();
    thrF.Abort();
    Console.ReadLine();
    }

    4.线程Join()方法
    Thread t = new Thread(aa);//aa()方法去执行其他代码
    t.IsBackground = true;
    t.Start();
    t.Join();//强制阻断其他线程执行,先执行当前线程
    Console.WriteLine("方法执行完毕");//这句代码会等到t这个线程执行完毕后才执行
    以上代码如果被另外一个线程调用时,t.Join()会阻断另外一个线程,等到t这个线程执行完毕后才执行

    5.委托的简单实用
    委托是用来保存一个方法的指针的
    如果方法的指针要被委托对象保存,那么这个方法的签名要和委托的签名一样。
    实用+=为委托对象追加方法
    public delegate void SayHi();
    SayHi s = new SayHi(Test);
    s+=Test1;
    s-=Test;
    s();

    6.GDI(图形设计接口)常用的方法
    //从panel1控件上创建一个画家Graphics对象
    using (Graphics g = Graphics.FromHwnd(this.panel1.Handle))
    {
    //g.DrawEllipse(Pens.Black, new Rectangle(0, 0, 100, 100));//画一个椭圆
    //g.DrawLine(Pens.Yellow, 10, 10, 100, 100);//画一条线
    //g.DrawArc(Pens.Black, new Rectangle(0, 0, 100, 100), 90, 90);//画一条弧线
    //g.DrawRectangle(Pens.Black,new Rectangle(0,0,100,200));//画一个矩形
    //g.DrawString("我是要写的字", new Font("微软雅黑", 12), new SolidBrush(Color.Red), new 
    PointF(10, 10));
    //g.FillEllipse(Brushes.Red, new Rectangle(0, 0, 100, 100));//用红色填充椭圆

    }
    //画水印
    using (Image img = new Bitmap(@"E:1.JPG"))
    {
    using (Graphics g = Graphics.FromImage(img))
    {
    using (Image img1 = new Bitmap(@"E:3.jpg"))
    {
    g.DrawImage(img1, 120, 177);
    }
    //g.DrawString("帅哥", new Font("微软雅黑", 30), new SolidBrush(Color.Red), new 
    PointF(10, 10));
    img.Save(@"E:2.jpg");
    }
    }

     
     
  • 相关阅读:
    多级联动系列——数组二级联动
    WebSocket初探
    8大最有气质的网络公司
    Quartz中时间表达式的设置-----corn表达式
    Servlet页面间对象传递的方法
    LSPCI具体解释分析
    CREATE PROCEDURE
    php实现工厂模式
    sql语法:inner join on, left join on, right join on具体用法
    C++虚函数表调用学习
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3415083.html
Copyright © 2020-2023  润新知