C#--lock锁

写在前面:

  在多线程编程中,可能会有许多线程并发的执行一段代码。在某些情况下,我们希望A中的代码块(B)同步的执行,即同一时刻只有一个线程执行代码块B,这就需要用到锁(lock)。lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待,已达到安全访问。
举一个例子:现有十个苹果,张三和李四同时吃这些苹果

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace LockTest
{
    class Program
    {
        private static int apple = 10;//10个苹果

        static void Main(string[] args)
        {
            Thread t1 = new Thread(() => EatApple("张三"));
            Thread t2 = new Thread(() => EatApple("李四"));
            t1.IsBackground = true;
            t2.IsBackground = true;
            t1.Start();
            t2.Start();
            Console.ReadKey();
        }

        private static void EatApple(string name)
        {
            while (true)
            {
                apple -= 1;
                Console.WriteLine(name + "正在吃苹果");
                Thread.Sleep(3000);
                Console.WriteLine(name + "吃完了,还剩" + apple + "个苹果\n");
                if (apple <= 0)
                    break;
            }
        }
    }
}

结果是这样的混乱:

                     

然后我们把共同访问的代码加上锁之后:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace LockTest
{
    class Program
    {
        private static int apple = 10;              //10个苹果
        private static object locker = new object();//创建锁
        static void Main(string[] args)
        {
            Thread t1 = new Thread(() => EatApple("张三"));
            Thread t2 = new Thread(() => EatApple("李四"));
            t1.IsBackground = true;
            t2.IsBackground = true;
            t1.Start();
            t2.Start();
            Console.ReadKey();
        }

        private static void EatApple(string name)
        {
            while (true)
            {
                lock (locker)//加锁
                {
                    apple -= 1;
                    Console.WriteLine(name + "正在吃苹果");
                    Thread.Sleep(3000);
                    Console.WriteLine(name + "吃完了,还剩" + apple + "个苹果\n");
                    if (apple <= 1)//变为1 不然会吃-1个苹果
                        break;
                }
            }
        }
    }
}

结果如下,加上锁之后呢,两个人就只能一个人一个人的去拿苹果吃。

lock用法:

其写法如下:

Object  locker = new Object();

lock(locker)

{
      //此处放置同步执行的代码
}

相当于:

private static object locker = new object();//创建锁

Monitor.Enter(locker); //排它锁
{
      //此处放置同步执行的代码
}
Monitor.Exit(locker); //释放指定对象上的排他锁

原文地址:https://www.cnblogs.com/mexihq/p/12632290.html

时间: 2024-10-10 04:49:20

C#--lock锁的相关文章

java.util.concurrent.locks lock锁【2】

Lock 锁介绍 JDK1.5以前,我们实现线程同步都是通过synchroized关键字进行方法或者语句块锁定,以保证该关键字作用域内的操作都是原子性操作. JDK1.5以后,提供的并发包提供了更强大的功能和更为灵活,最为关键的是需要手工释放锁,需要unlock必须在finally方法内.这是非常值得注意的事情. 介绍一下Lock接口.实现类有3个,分别是 普通锁,读写锁-写锁,读写锁-读锁. API文档给出了相近的说明和demo. Lock l = ...; l.lock(); try { /

多线程之Lock锁和读写锁ReadWriteLock

JDK1.5之后有提供了另一种加锁方式Lock锁.Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作.此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的Condition 对象. 锁是控制多个线程对共享资源进行访问的工具.通常,锁提供了对共享资源的独占访问.一次只能有一个线程获得锁,对共享资源的所有访问都需要首先获得锁.不过,某些锁可能允许对共享资源并发访问,如ReadWriteLock 的读取锁. synchronized 方法或语句的使用

Lock锁的使用示例

Lock锁是java5用来代替synchronized的一种面向对象的锁的方案 1 public class LockDemo { 2 /** 3 * Lock是用来替换synchronized, 优点是Lock 更加面向对象.eclipse查看接口所有的实现类用CTRL+T 4 */ 5 6 public static void main(String[] args) { 7 final OuterLoop loop = new OuterLoop(); 8 9 for (int i = 0;

转: 【Java并发编程】之二十:并发新特性—Lock锁和条件变量(含代码)

简单使用Lock锁 Java5中引入了新的锁机制--Java.util.concurrent.locks中的显式的互斥锁:Lock接口,它提供了比synchronized更加广泛的锁定操作.Lock接口有3个实现它的类:ReentrantLock.ReetrantReadWriteLock.ReadLock和ReetrantReadWriteLock.WriteLock,即重入锁.读锁和写锁.lock必须被显式地创建.锁定和释放,为了可以使用更多的功能,一般用ReentrantLock为其实例化

JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题

JAVA基础再回首(二十五)--Lock锁的使用.死锁问题.多线程生产者和消费者.线程池.匿名内部类使用多线程.定时器.面试题 版权声明:转载必须注明本文转自程序员杜鹏程的博客:http://blog.csdn.net/m366917 我们来继续学习多线程 Lock锁的使用 虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock Lock void lock():获取锁 v

Lock锁_线程_线程域

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Windows.Forms; namespace Lock锁_线程_线程

Java并发编程系列之十六:Lock锁

Lock锁简介 Lock锁机制是JDK 5之后新增的锁机制,不同于内置锁,Lock锁必须显式声明,并在合适的位置释放锁.Lock是一个接口,其由三个具体的实现:ReentrantLock.ReetrantReadWriteLock.ReadLock 和 ReetrantReadWriteLock.WriteLock,即重入锁.读锁和写锁.增加Lock机制主要是因为内置锁存在一些功能上局限性.比如无法中断一个正在等待获取锁的线程,无法在等待一个锁的时候无限等待下去.内置锁必须在释放锁的代码块中释放

Java并发编程深入学习——Lock锁

Lock锁介绍 ??在Java 5.0之前,在协调对共享对象的访问时可以使用的机制只有synchronized和volatile.Java 5.0 增加了一种新的机制:ReentrantLock.它并不是一种替代内置加锁的方法,而是当内置加锁机制不适用时,作为一种可选择的高级功能. Lock接口 Lock接口位于java.util.concurrent.locks包中,它定义了一组抽象的加锁操作. public interface Lock { //获取锁 void lock(); // 如果当

java 线程七-Lock锁

JDK1.5中提供了多线程升级解决方案. 将同步synchronized替换成显式Lock操作. 将Object中的wait,notify,notifyAll,替换成了condition对象.该对象可以通过Lock锁进行获取. 一个Lock锁可以生成多个condition对象. 该示例中实现了本方只唤醒对方的操作. import java.util.concurrent.locks.*; class Resource { private String name; private int num=

java并发编程的艺术——第五章总结(Lock锁与队列同步器)

Lock锁 锁是用来控制多个线程访问共享资源的方式. 一般来说一个锁可以防止多个线程同时访问共享资源(但有些锁可以允许多个线程访问共享资源,如读写锁). 在Lock接口出现前,java使用synchronized关键字实现锁的功能,但是在javaSE5之后,并发包中提供了Lock接口(以及其实现类)用来实现锁的功能. Lock提供了与synchronized相似的功能,但必须显示的获取锁与释放锁,虽然不及隐式操作方便,但是拥有了锁获取与释放的可操作性.可中断的锁获取与超时获取锁等多重功能. 提供