Java中同步与并发用法分析

Java中同步与并发用法分析

同步

在Java中,同步是指多个线程之间访问共享资源的时候,保证线程安全的机制。Java提供了两种机制来实现同步:synchronized关键字和Lock接口。

synchronized关键字

synchronized关键字可以用于修饰方法或代码块。被修饰的方法或代码块在同一时间只能被一个线程执行,其他线程需要等待。

示例代码:

public class ThreadSafeExample {
    private int count = 0;

    // synchronized关键字修饰方法
    public synchronized void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

在上述例子中,increment()方法被synchronized关键字修饰,意味着在同一时间只有一个线程能够访问它。如果不加synchronized关键字,多个线程同时访问increment()方法可能会出现线程安全问题。

Lock接口

Lock接口提供了与synchronized关键字类似的同步机制,也可以用于保证多个线程之间的线程安全。

示例代码:

public class ThreadSafeExample {
    private int count = 0;
    private Lock lock = new ReentrantLock();  // 实例化Lock接口对象

    public void increment() {
        lock.lock();  // 加锁
        try {
            count++;
        } finally {
            lock.unlock();  // 解锁
        }
    }

    public int getCount() {
        return count;
    }
}

在上述例子中,我们使用了Lock接口提供的ReentrantLock实现类来实例化lock对象。在increment()方法中,我们调用了lock()方法加锁,finally中调用了unlock()方法解锁。这样,在同一时间只有一个线程能够访问increment()方法,可以保证线程安全。

并发

Java中的并发是指多个线程同时执行,在同一时间内,每个线程都可以访问共享资源。

Java提供了多种工具来处理并发,最常用的有:

  • Semaphore信号量
  • CountDownLatch计数器
  • CyclicBarrier屏障

Semaphore信号量

Semaphore可以用来控制同时访问共享资源的线程数量。Semaphore类似于一个计数器,可以通过acquire()和release()方法来控制资源的访问。

示例代码:

public class SemaphoreExample {
    private static final int THREAD_COUNT = 10;
    private static Semaphore semaphore = new Semaphore(5);  // 实例化Semaphore对象,初始许可数量为5

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();

        for (int i = 0; i < THREAD_COUNT; i++) {
            executorService.execute(() -> {
                try {
                    semaphore.acquire();  // 获取许可
                    System.out.println(Thread.currentThread().getName() + " acquire a permit");
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();  // 释放许可
                    System.out.println(Thread.currentThread().getName() + " release a permit");
                }
            });
        }

        executorService.shutdown();
    }
}

在上述例子中,Semaphore的初始许可数量为5,每个线程获取一个许可,线程执行结束后释放许可。最多只有5个线程能够同时占用许可,其他线程需要等待。

CountDownLatch计数器

CountDownLatch可以用来实现等待其他线程执行完毕之后再进行操作。CountDownLatch的初始计数器数量为线程个数,每个线程执行完后计数器数量减1,当计数器数量为0时,await()方法才会返回。

示例代码:

public class CountDownLatchExample {
    private static final int THREAD_COUNT = 5;
    private static CountDownLatch countDownLatch = new CountDownLatch(THREAD_COUNT);  // 实例化CountDownLatch对象,计数器数量为5

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();

        for (int i = 0; i < THREAD_COUNT; i++) {
            executorService.execute(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + " started");
                    Thread.sleep(2000);
                    System.out.println(Thread.currentThread().getName() + " ended");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    countDownLatch.countDown();  // 计数器减1
                }
            });
        }

        countDownLatch.await();  // 等待计数器归零

        System.out.println("All threads have finished.");
        executorService.shutdown();
    }
}

在上述例子中,我们创建了5个线程,执行其中的任务,任务执行完成后调用countDown()方法减少计数器数量。执行主线程中,通过await()方法等待所有线程执行完毕,当计数器数量变为0时,执行主线程中的代码。

CyclicBarrier屏障

CyclicBarrier可以用来在多个线程之间创建一个屏障,只有所有线程到达屏障时,才会继续执行后续操作。

示例代码:

public class CyclicBarrierExample {
    private static final int THREAD_COUNT = 5;
    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(THREAD_COUNT, () -> {
        System.out.println("All threads have reached the barrier.");
    });  // 实例化CyclicBarrier对象,等待线程数量为5

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();

        for (int i = 0; i < THREAD_COUNT; i++) {
            executorService.execute(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + " started");
                    Thread.sleep(2000);
                    cyclicBarrier.await();  // 等待其他线程到达屏障
                    System.out.println(Thread.currentThread().getName() + " ended");
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            });
        }

        executorService.shutdown();
    }
}

在上述例子中,我们创建了5个线程,执行其中的任务,并在其中增加了cyclicBarrier.await()方法。当线程调用这个方法时,它就等待其他线程也到达这个屏障。当所有线程都到达屏障时,CyclicBarrier的内部计数器就会被重置为其初始值,并启动一个可选的Runnable。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java中同步与并发用法分析 - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • 彻底搞懂Java多线程(四)

    我来详细讲解一下“彻底搞懂Java多线程(四)”的完整攻略。 标题 彻底搞懂Java多线程(四) 具体内容 Java多线程中的一个重要概念就是线程池,线程池可以有效地管理线程的数量,防止资源被浪费,提高程序的性能。本篇文章将详解Java中的线程池。 线程池实现原理 Java中的线程池由Executor框架提供。Executor框架定义了ThreadPoolE…

    多线程 2023年5月17日
    00
  • Java 高并发三:Java内存模型和线程安全详解

    《Java 高并发三:Java内存模型和线程安全详解》涉及了Java内存模型以及线程安全的概念和实现方法,主要内容如下: 1. Java内存模型 1.1 基础概念 介绍了JMM的概念、线程之间的通信和同步的原理、原子性、可见性和有序性的概念。在文字说明的同时,还提供了可视化图示,方便读者直观理解。 1.2 重排序 讲解了编译器和处理器的重排序问题。通过示例,…

    多线程 2023年5月16日
    00
  • java并发编程专题(五)—-详解(JUC)ReentrantLock

    Java并发编程专题(五)——详解(JUC)ReentrantLock ReentrantLock是java.util.concurrent(J.U.C)包中的一个锁工具类,也是Java多线程中常用的互斥锁。它可用于代替synchronized关键字进行线程同步,比synchronized更灵活。 1. 使用ReentrantLock 1.1 创建Reent…

    多线程 2023年5月16日
    00
  • MySQL MVVC多版本并发控制的实现详解

    MySQL MVCC多版本并发控制的实现详解 什么是MVCC MVCC全称为Multi-Version Concurrency Control,即多版本并发控制。它是一种在数据库管理系统的事务处理中,用于保证事务并发执行时的数据一致性和隔离性的技术。在MySQL数据库中, MVCC 主要用于实现行级锁。 MVCC的基本原理 MVCC基于快照的概念,每个事务启…

    多线程 2023年5月16日
    00
  • Java多线程之Worker Thread模式

    Java多线程之Worker Thread模式 什么是Worker Thread模式 Worker Thread模式是一种有效的多线程设计模式,用于在并发环境中处理多个请求,提高应用的响应性能和并发能力。 在Worker Thread模式中,主线程负责接收任务,把任务交给线程池中的工作线程去处理,主线程不断地接收任务,工作线程不断地从队列中取出任务并执行,一…

    多线程 2023年5月17日
    00
  • Java多线程之搞定最后一公里详解

    Java多线程之搞定最后一公里详解 简介 多线程是Java重要的特性之一,它可以使程序变得更加高效和快速,提升用户体验。对于Java开发者来说,不了解多线程的相关概念和技术点就无法达到高超的开发水平。本篇文章主要讲解Java多线程的最后一公里,即如何处理并发的关键问题。 如何处理并发关键问题 1. 竞态条件 竞态条件是多线程编程中最常见的问题之一。它所指的是…

    多线程 2023年5月17日
    00
  • python 多线程串行和并行的实例

    下面是关于“python 多线程串行和并行的实例”的完整攻略。 什么是多线程? 多线程是指在一个程序中,有多个县城同时进行,每个线程可以执行不同的任务。在多线程程序中,进程内的多个线程共享程序的内存空间,进程拥有的系统资源在多个线程之间共享,因此进程之间的切换代价远比线程之间的切换代价更大。 多线程的优势 多线程编程有以下优势: 改善程序响应速度,因为多个线…

    多线程 2023年5月17日
    00
  • 详解Java实现多线程的三种方式

    详解Java实现多线程的三种方式 Java是一种支持多线程的语言,多线程可以带来更快的程序速度和更好的用户体验。Java实现多线程的方式有三种,分别是继承Thread类、实现Runnable接口和实现Callable接口。本文将详细介绍这三种方式的实现方法和示例代码。 继承Thread类 继承Thread类是Java实现多线程的一种方式。我们需要创建一个继承…

    多线程 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部