`
javandroid
  • 浏览: 25577 次
  • 性别: Icon_minigender_1
文章分类
社区版块
存档分类
最新评论

多线程之二 线程同步

 
阅读更多

线程同步的7种方式
线程同步的5种方式
线程同步的3种方式

1.同步方法(synchronized)

由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。

内置锁是可以重入的,当某个线程试图获取一个由它自己持有的锁,这个请求会成功。
注:synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类。

优点:简单,直观,代码可读性高
缺点:效率低

2.同步代码块(synchronized)

即有synchronized关键字修饰的语句块。被该关键字修饰的语句块会自动被加上内置锁,从而实现同步
注:同步是一种高开销的操作,因此应该尽量减少同步的内容。通常没有必要同步整个方法,使用synchronized代码块同步关键代码即可。


3.重入锁(ReentrantLock)

在JavaSE5.0中新增了一个java.util.concurrent包来支持同步。ReentrantLock类是可重入、互斥、实现了Lock接口的锁, 它与使用synchronized方法和快具有相同的基本行为和语义,并且扩展了其能力。

重入锁可以完全替代synchronized关键字。在JDK5.0的早期版本中,重入锁的性能远远好于synchronized。但从JDK6.0版本开始,JDK在synchronized上做了大量优化,使得两者的差距并不大。-----《实战Java高并发程序设计》
重入锁并不是一种替代内置锁的方法,而是当内置锁不适用时,作为一种可选的高级功能。-----《实战Java高并发程序设计》P227


开发人员必须手动指定何时加锁,何时释放锁。正因如此,重入锁对逻辑控制的灵活性远远好于synchronized。
退出临界区时,必须记得释放锁,否则,其它线程就没有机会再访问临界区了。

ReenreantLock类的常用方法有:
ReentrantLock() : 创建一个ReentrantLock实例
lock() : 获得锁
unlock() : 释放锁
注:ReentrantLock()还有一个可以创建公平锁的构造方法,但由于能大幅度降低程序运行效率,不推荐使用


4.volatile

a.volatile关键字为域变量的访问提供了一种免锁机制
b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新
c.因此每次使用该域就要重新计算,而不是使用寄存器中的值
d.volatile不能保证原子性,也不能用来修饰final类型的变量


5.ThreadLocal

如果说加锁是解决同步的一种思路,那么ThreadLocal就是另外一种解决同步的思路。ThreadLocal为每个线程提供一个共享对象的副本,只有当前线程才能访问。这样一来,线程间就不存在竞争了。


6.信号量(Semaphore)

信号量为多线程协作提供了更为强大的控制方法。广义上说,信号量是对锁的扩展。无论是内部锁synchronized还是重入锁ReentrantLock,一次都只允许【一个】线程访问一个资源,而信号量却可以指定【多个】线程同时访问一个资源。

public class SemaphoreDemo {

    public static void main(String[] args) {
        // 线程池。信号量通常都是针对多个线程,直接使用线程池实现
        ExecutorService exec = Executors.newCachedThreadPool();        
        final Semaphore semaphore = new Semaphore(2);//每次允许2个线程获得许可

        // 模拟20个客户端访问
        for (int i = 0; i < 20; i++) {
            final int num = i;
            
            Runnable run = new Runnable() {
                public void run() {
                    try {
                        // 获取许可
                        semaphore.acquire();
                        System.out.println("Accessing: " + num);
                        
                        Thread.sleep(3000);
                        // 访问完后,释放 
                        semaphore.release();
                    } catch (InterruptedException e) {
                    }
                }
            };
            
            exec.execute(run);
        }
        // 退出线程池
        exec.shutdown();
    }
}




分享到:
评论

相关推荐

    MFC 多线程及线程同步

    MFC 多线程及线程同步 MFC 多线程及线程同步 MFC 多线程及线程同步

    使用三种VC的多线程同步方法编写一个多线程的程序

    1.使用三种VC的多线程同步方法编写一个多线程的程序(要求在屏幕上先显示Hello,再显示World)。 1)基于全局变量的多线程同步程序; 2)基于事件的多线程同步程序; 3)基于临界区的多线程同步程序。

    3种多线程实现同步方法

    本篇文章将深入探讨三种在C++中实现多线程同步的方法:事件对象、关键代码段和互斥对象。 首先,我们来看**事件对象**。事件对象是一种信号机制,用于线程间通信和同步。在Windows API中,CreateEvent函数创建一个...

    Java多线程同步.pdf

    Java多线程同步是指在Java语言中,如何使用synchronized关键字和其他同步机制来确保多线程程序的正确执行。在Java语言中,synchronized关键字用于对方法或者代码块进行同步,但是仅仅使用synchronized关键字还不能...

    Delphi多线程同步的例子

    本文将深入探讨Delphi中的多线程和线程同步,并以"SortThreads"和"delphi-thread-gui"这两个示例项目为例,讲解如何在实践中应用这些概念。 1. **多线程**:多线程允许应用程序同时执行多个独立的任务,提高程序的...

    VC++多线程同步基本示例

    在编程领域,尤其是在Windows平台下开发C++应用时,多线程技术是非常关键的一部分,它允许程序同时执行多个任务,从而提升系统效率。...因此,对多线程同步的理解和应用能力是每个专业程序员必备的技能之一。

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

    满足这两个条件,就可以不用进行线程同步啦! 如何保证读在写之后呢,方法有多种,比如 读线程判断条件if(读指针 == 写指针)。写线程判断条件 if(下一个指针==读线程指针) 其实这就是一简单的生产者与消费者问题。 ...

    MFC多线程同步类的使用

    【MFC多线程同步类的使用】 在MFC(Microsoft Foundation Classes)中,多线程编程是一项重要的技术,尤其在开发复杂的、并发执行的任务时。多线程允许程序同时执行多个任务,提升效率和响应速度。然而,线程间的...

    多线程的同步机制 VC++

    总的来说,多线程同步机制,尤其是Event的使用,是实现多线程程序高效、安全运行的关键。开发者需要根据具体需求选择合适的同步策略,防止竞态条件、死锁等问题的发生,确保程序的正确性和性能。理解并熟练运用这些...

    多线程数据同步

    标题"多线程数据同步"直指这一核心问题,而描述则具体提到了使用临界区对象作为解决方案之一。 线程同步是为了防止多个线程同时访问共享资源,导致数据的混乱。在Windows操作系统中,临界区对象是一种轻量级的同步...

    C#实现多线程同步并发操作

    本文将深入探讨如何在C#中实现多线程同步并发操作,这不仅对于提高软件性能至关重要,也是高级程序员必须掌握的核心技能之一。 ### C#中的多线程同步并发操作 多线程编程可以极大地提高CPU的利用率,特别是在处理I...

    多线程同步和通讯完整示例

    在编程领域,尤其是在Java这样的多线程环境中,理解和掌握多线程同步与通讯至关重要。本文将深入探讨这些概念,以及如何使用synchronized关键字、wait-notify机制和Lock接口来实现线程间的同步与通讯。 首先,多...

    多线程临界段同步演示1

    然而,多线程编程也带来了一些挑战,其中之一就是如何确保线程安全,即在多线程环境下正确地共享数据。这里我们将深入探讨"多线程临界段同步"的概念,以及如何通过API方式实现它,而不是依赖MFC(Microsoft ...

    多线程及线程同步

    然而,多线程环境下也带来了一些问题,尤其是资源竞争和数据一致性问题,这些问题需要通过线程同步机制来解决。本文将详细介绍如何通过临界区、互斥内核对象、事件内核对象和信号量内核对象来实现线程同步。 1. ...

    简单实现多线程同步示例(模拟购票系统)

    本示例“简单实现多线程同步示例(模拟购票系统)”旨在通过一个具体的实例,帮助开发者理解如何在Java中创建并管理多线程以及如何实现线程同步,确保数据的一致性和正确性。 首先,我们要明确多线程的基本概念。在...

    多线程的批量线程同步解决方案

    二、线程同步 线程同步是多线程编程中的重要概念,用于控制不同线程间的执行顺序和访问共享资源的方式,防止竞态条件和死锁的发生。常见的线程同步机制包括: 1. **互斥量(Mutex)**:一种简单的同步机制,一次只有...

    delphi多线程传递参数及同步二

    三、线程同步 当线程处理完数据后,可能需要将结果返回给主线程,或者更新主线程中的控件。由于多个线程同时访问同一资源可能导致竞态条件,所以我们需要使用同步机制。 Delphi 提供了几种同步机制,如 TEvent, ...

    c++多线程同步——信号量

    在C++编程中,多线程同步是一种关键的技术,它允许多个执行线程协同工作,以避免数据竞争和死锁等并发问题。信号量(Semaphore)是实现多线程同步的一种有效工具,常用于控制对共享资源的访问。在这个名为"Mthread11...

    操作系统实验多线程同步(含C++源代码)

    操作系统中的多线程同步是一个关键概念,特别是在并发编程中,它涉及到如何协调多个线程以避免数据不一致性和竞态条件。在这个实验中,我们关注的是C++编程语言中的实现,以及操作系统如何处理线程的优先级。 首先...

    多线程代码 经典线程同步互斥问题 生产者消费者问题

    c: 多线程访问同一资源 d: 经典线程同步互斥问题 e: 使用关键段解决子线程互斥问题 f: 利用事件实现线程同步问题 g: 利用互斥量来解决线程同步互斥问题 h: problem1 生产者消费者问题 (1生产者 1消费者 1...

Global site tag (gtag.js) - Google Analytics