`
bjlf1105
  • 浏览: 25481 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

线程:共享资源(二)

阅读更多
synchronized关键字被添加到实例方法的前面时,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法(对象级的锁)
SomeClass中的同步方法:
public synchronized (static) void dosomething() {
while (true) {
System.out.println(Thread.currentThread().getName()
+ ":dosomething");
}

}
public synchronized (static) void doit() {
while (true) {
System.out.println(Thread.currentThread().getName() + ":doit");
}
}
1、放在实例方法前面(即那些非具体方法)
while(true)时两个线程能同时进到方法里边,分别调用dosomething方法交替的进行着。但当我们设置synchronized关键字在dosomething方法前面时,这时候就只有一个线程先调用dosomething方法了,具体是哪个线程先抢到这把锁,即这个对象的锁,抢到了他就能访问有这把锁控制的那些方法。因为这dosomething是个死循环,那么另一个线程永远都得不到机会执行这个方法。
      任何一个对象都有一把锁,可以想象创建一个对象后就已经有锁了。现在再添加一个doit方法,但没有在该方法前面设置synchronized关键字,因此这是两个线程都能访问到这个方法,因为这个方法是Someclass这个对象的一个方法,而Client中的两个线程,都使用到了Someclass这个对象的共享资源,所以也是交替的执行着doit方法。但如果在doit方法前面设置为同步的话即synchronized,那么根据同步的特性,这个方法对于这个对象来说是同步的,因为前面的dosomething方法是同步的,所以呢doit必须等到前面的dosomething方法执行完才会执行它的操作,显然它没有机会执行了。务必要注意上面两个线程调用的是同一个对象,如果在MyThread中new SomeClass的话,那么这是两个不同的sc对象了。因此dosomething和doit方法都能调用到,是针对的是同一对象而言的
可以把sc想成是一个房间,房间里边的有一堆synchronized定义的方法,房外面有一堆人在等,谁抢到了这把锁就可以进去,其他等待中直到进去的人出来后,某人才能拿到这把锁进去执行里边的方法,因此synchronized是一个四周围起来的围墙,只有拿到这把锁才能进去,相当于一个临界区。如果不是synchronize修饰的方法则没有这个围墙,任何人任何时刻想进去就进去执行操作。
2、放到静态方法前面的时候,只有一个线程可以调用这个类的静态方法(类级别的锁)
把上面的两个方法改成static,那么锁就是加在这个类上了,如果把其中一个static去掉的话,那么这时候就有两把锁,分别是指这个对象和这个类的锁,由于锁的范围不同,因此都能同时访问
public void doit() {
for (int i = 0; i < 23; i++) {
System.out.println("for循环"+i);
}
synchronized (this) {
while (true) {
System.out.println(Thread.currentThread().getName() + ":doit");
}
}

}
3、synchronized同步代码块
有时候,如果将synchronized关键字定义在方法前面的话,显得控制的粒度太粗糙了,可以对方法内部涉及到共享资源部分的访问放到同步块中即可。
synchronized (this或者其他对象或者类级别锁) {},关键是要弄清楚锁的范围,在同一个锁范围内是不允许有两个同步块同时执行的,一个synchronized必须等另一个synchronized方法执行完后才能进行。
可以想象这是不同的临界区房间,定义了不同的锁,同步代码块中必须指定一个对象,这个对象的锁被用来控制对这段代码的访问,只有线程获得了这个对象的锁之后,才可以访问,上面中this可以SomeClass类或者其他自己定义的对象,他们分别是不同的锁

线程:互斥与协作

Synchronized控制的资源,就像四周围墙围起来一样,外边的线程想进来拿到这把锁,进到这个房间,操作里面的一些方法,只要有人还持有这把锁没有释放,其他线程只能等待。
通过wait和notify方法这种监视器模型——互斥与协作,对这把锁进行控制,想要取得这把锁就必须等待取得这把锁,操作锁里边的资源,用完了要通知别的线程,从而保证线程的工作,最大限度地利用线程。
CountDownLatch:cd线程计数器
  cd.await()等待所有线程执行完毕
  cd.countDown所有的线程结束

wait和sleep的区别
wait是Object类中的方法,而sleep是Thread中的方法
wait只能在synchronized里面用,而且要注意synchronized锁定的是哪个对象,你只能调用那个对象的wait方法
wait会释放锁,而sleep不会

volatile:为了提高线程性能所产生的一个小BUG,在多线程中JVM可能会优化这个值,每个线程都会保留它自己的副本,其他人可能压根儿看不到。而volatile就是避免线程创建本地副本的属性,避免线程本地优化性能,从而直接在主存中修改,一改大家都能看到。这就是线程的可见性,但是他不能避免线程的有序性,因为每个人都是直接操作主存的,大家都能看到这个值的变化,谁都可以在任何时刻修改它。而synchronized则控制了这种有序性,保证大家都能看到的同时,而你必须等里面的那个人把锁释放掉才有机会去操作它,这就保证了线程的有序性。
分享到:
评论

相关推荐

    多线程不同步读写共享资源代码

    多线程不同步读写共享资源 文章配套代码 我在很早的时候就听说多线程不同步是可以读写共享资源的。这听起来感觉挺好,因为一旦同步线程,将在同步线程上花去一定的CPU时间片. 这一切都是真的,但是,不同步线程的...

    [Java]多线程:共享资源同步——不认真看你会后悔的

    在进行多线程开发时最令人头痛的问题估计就是对共享资源的控制了吧,今天就让我们谈一谈这个问题吧。 共享资源顾名思义就是需要被多个线程使用的资源,但是很多情况下我们是不能允许多个线程同时使用这个资源的。这...

    12.1 Qt5多线程:多线程及简单实例

    - 避免在线程之间共享复杂的Qt对象,除非使用`QThread::moveToThread()`移动对象。 总结,Qt5的多线程机制是通过QThread类实现的,它允许开发者创建独立的工作线程来处理后台任务,从而保持主线程的流畅性。`...

    多线程:CSemaphore.rar

    2. **同步机制**:当一个线程完成对共享资源的操作后,必须释放Semaphore,增加其计数值,以便其他等待的线程可以继续执行。这样,Semaphore就充当了线程间的协调者,确保资源的有序访问。 3. **避免死锁**:通过...

    12.2 Qt5多线程:使用信号量实现生产者和消费者

    QSemaphore提供了一种计数信号量机制,它维护一个非负整数值,允许特定数量的线程访问共享资源。当资源可用时,线程可以获取(acquire)一个许可证,然后访问资源;当资源被使用后,线程释放(release)许可证,使...

    多线程资源共享集合

    `synchronized`关键字是Java中用来控制多线程并发访问共享资源的一种机制。它提供了互斥访问,确保同一时间只有一个线程可以执行特定代码块。`synchronized`可以修饰方法或者代码块,当一个线程进入`synchronized`...

    ThreadLocked多线程共享资源

    "ThreadLocked多线程共享资源"这个主题,就是探讨如何在C#中有效地管理和保护这些共享数据,以确保线程安全。 一、线程锁概念 线程锁是一种同步机制,用于限制对特定代码段的并发访问。在C#中,主要的线程锁包括`...

    NET中多线程间资源共享与访问

    在.NET环境中,多线程编程是一项重要的技能,尤其当涉及到并发访问共享资源时。本文档深入探讨了.NET平台上的多线程资源共享与访问机制,并详细介绍了一个自定义类`ThreadLockHelper`,该类能有效地管理线程间的资源...

    医学-医疗多线程共享资源分配处理方法及系统.zip

    本文档“医疗多线程共享资源分配处理方法及系统”深入探讨了如何在医疗环境中利用多线程技术优化资源分配,提高系统的响应速度和整体性能。 一、多线程基础 1. 多线程概念:多线程是指在一个进程中可以同时存在多...

    多线程的运用e语言多线程 e多线程

    3. 资源复用:多线程共享进程资源,减少内存开销。 缺点: 1. 线程安全:线程间的数据共享可能导致数据竞争和死锁。 2. 调度开销:线程的创建、销毁和上下文切换都有一定的系统开销。 3. 资源限制:过多的线程可能...

    12.2 Qt5多线程:使用QWaitCondition实现生产者和消费者

    1. **共享资源**:首先,我们需要一个共享的数据结构,例如一个队列,来存储生产者产生的数据。这个队列需要是线程安全的,因此可以使用Qt提供的`QMutex`来保护。 2. **生产者线程**:生产者线程会生成数据并尝试将...

    c#多线程编程第二版[2016]

    - 线程同步:使用C#的lock关键字或者Monitor类对共享资源进行锁定操作,保证线程安全。 2. 线程同步 - 原子操作:介绍如何在多线程中执行简单的原子操作,这些操作可以保证数据的一致性。 - 使用Mutex:Mutex是...

    多线程操作共享文件.zip

    在IT领域,多线程操作共享文件是一项关键的技术,尤其在并发编程中。Delphi作为一款强大的面向对象的 Pascal 编程环境,提供了丰富的工具和类库来支持这样的任务。本压缩包“多线程操作共享文件.zip”显然是一个关于...

    使用redis分布式锁解决并发线程资源共享问题

    众所周知, 在多线程中,因为共享全局变量,会导致资源修改结果不一致,所以需要加锁来解决这个问题,保证同一时间只有一个线程对资源进行操作 但是在分布式架构中,我们的服务可能会有n个实例,但线程锁只对同一个...

    Java多线程

    线程总是属于某个进程,并且同一进程内的多个线程共享该进程的内存资源。 **2. Java中的线程** 在Java中,“线程”主要涉及两个方面: - **java.lang.Thread类的实例**:表示线程对象,拥有自己的变量和方法,...

    操作系统原理线程概念与应用 操作系统原理线程概念与应用

    - 线程安全:多个线程访问共享资源可能导致数据不一致,需要同步机制如锁、信号量等来确保数据一致性。 - 资源限制:虽然线程轻量,但过多的线程可能会消耗大量内存,尤其是在处理大量线程时。 - 死锁:线程间的相互...

    多线程开发及其源代码

    3. 线程安全:确保多线程访问共享资源时不会出错。使用原子操作、线程局部存储、不可变对象等方式增强线程安全性。 四、源代码分析 压缩包中的`MultiThreadA`可能是包含一系列多线程编程实例的文件,如简单的线程...

    windowsC++多线程加锁信号量共享内存

    通过阅读和理解这个文件,开发者可以学习到如何在实际项目中有效地管理和保护共享资源,避免数据竞争和死锁,提高程序的稳定性和效率。 总的来说,理解并熟练运用这些技术是成为一名优秀的Windows C++多线程程序员...

    c#多线程编程实战(原书第二版)源码

    这些机制用于控制对共享资源的访问,确保线程安全。源码中可能会展示如何在多个线程间同步操作。 3. **线程池**:线程池是C#中的一个重要特性,它能有效管理线程生命周期,提高系统效率。`ThreadPool`类提供了异步...

Global site tag (gtag.js) - Google Analytics