Java并发编程多线程间的同步控制和通信详解

Java并发编程多线程间的同步控制和通信详解

背景介绍

在多线程并发编程中,控制多个线程的同步和通信是非常重要的话题。如果多个线程之间没有良好的同步控制和通信机制,就会导致数据竞争、死锁、饥饿等问题,从而降低程序的性能和可靠性。因此,在Java并发编程中,多线程间的同步控制和通信是一项非常重要的技能。

同步控制

什么是同步控制?

同步控制是一种机制,用于确保多个线程之间可以协调工作,防止数据竞争和不确定性问题。Java中使用synchronized关键字和Lock对象提供同步控制。

synchronized关键字的使用方法

synchronized关键字是Java中提供最常用的同步控制机制。它可以用于修饰方法和代码块,并且只有一个线程可以访问被synchronized关键字修饰的代码。示例代码如下:

public class SynchronizedExample {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }
}

在上面的代码中,increment方法被synchronized关键字修饰,表示该方法是一个同步方法,只有一个线程可以同时执行该方法。

Lock对象的使用方法

Lock对象是Java中提供的另一种同步控制机制。相比synchronized关键字,Lock对象提供了更加细粒度的控制和更高的性能。示例代码如下:

public class LockExample {
    private Lock lock = new ReentrantLock();
    private int count = 0;

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }
}

在上面的代码中,increment方法使用了Lock对象进行同步控制。通过lock.lock()方法获取锁对象,并在finally语句块中使用lock.unlock()方法释放锁对象。

通信机制

什么是通信机制?

通信机制是指多个线程之间可以协调工作,进行数据交换和同步操作的机制。Java中使用wait(), notify()和notifyAll()方法提供通信机制。

wait()和notify()的使用方法

wait()和notify()方法是Object类中提供的方法,可以用于在多个线程之间进行等待和唤醒的操作。示例代码如下:

public class WaitNotifyExample {
    private Object lock = new Object();
    private int count = 0;

    public void increment() throws InterruptedException {
        synchronized (lock) {
            while (count == 5) {
                lock.wait();
            }

            count++;
            System.out.println("Thread " + Thread.currentThread().getId() + " incremented count to " + count);

            lock.notify();
        }
    }

    public void decrement() throws InterruptedException {
        synchronized (lock) {
            while (count == 0) {
                lock.wait();
            }

            count--;
            System.out.println("Thread " + Thread.currentThread().getId() + " decremented count to " + count);

            lock.notify();
        }
    }
}

在上面的代码中,increment()和decrement()方法使用了wait()和notify()方法进行通信操作。当count等于5时,increment()方法会调用lock.wait()方法进行等待,直到其他线程通过lock.notify()方法唤醒它。当count等于0时,decrement()方法也会调用lock.wait()方法进行等待,直到其他线程通过lock.notify()方法唤醒它。

notifyAll()的使用方法

notifyAll()方法是Object类中提供的另一种唤醒等待线程的方法。与notify()方法不同,notifyAll()方法会唤醒所有正在等待的线程。示例代码如下:

public class NotifyAllExample {
    private Object lock = new Object();
    private int count = 0;

    public void increment() throws InterruptedException {
        synchronized (lock) {
            while (count == 5) {
                lock.wait();
            }

            count++;
            System.out.println("Thread " + Thread.currentThread().getId() + " incremented count to " + count);

            lock.notifyAll();
        }
    }

    public void decrement() throws InterruptedException {
        synchronized (lock) {
            while (count == 0) {
                lock.wait();
            }

            count--;
            System.out.println("Thread " + Thread.currentThread().getId() + " decremented count to " + count);

            lock.notifyAll();
        }
    }
}

在上面的代码中,increment()和decrement()方法使用了notifyAll()方法进行通信操作。如果有多个线程等待进入synchronized代码块,notifyAll()方法会唤醒所有等待线程,而不是唤醒其中一个线程。

示例说明

示例1:使用synchronized关键字进行同步控制

下面的示例代码演示了如何使用synchronized关键字进行同步控制:

public class SynchronizedExample {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public void run() {
        for (int i = 0; i < 100000; i++) {
            increment();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynchronizedExample se = new SynchronizedExample();

        Thread t1 = new Thread(se::run);
        Thread t2 = new Thread(se::run);

        t1.start();
        t2.start();
        t1.join();
        t2.join();

        System.out.println("Count: " + se.count);
    }
}

在上面的代码中,SynchronizedExample类中的increment()方法被synchronized关键字修饰,表示该方法是一个同步方法。在main()方法中,创建了两个线程t1和t2,并分别调用了SynchronizedExample类中的run()方法。通过运行该程序,输出的结果应该为:Count: 200000

示例2:使用wait()和notify()方法进行线程通信

下面的示例代码演示了如何使用wait()和notify()方法进行线程间的通信:

public class WaitNotifyExample {
    private Object lock = new Object();
    private int count = 0;

    public void increment() throws InterruptedException {
        synchronized (lock) {
            while (count == 5) {
                lock.wait();
            }

            count++;
            System.out.println("Thread " + Thread.currentThread().getId() + " incremented count to " + count);

            lock.notify();
        }
    }

    public void decrement() throws InterruptedException {
        synchronized (lock) {
            while (count == 0) {
                lock.wait();
            }

            count--;
            System.out.println("Thread " + Thread.currentThread().getId() + " decremented count to " + count);

            lock.notify();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        WaitNotifyExample wne = new WaitNotifyExample();

        Runnable r1 = () -> {
            try {
                for (int i = 0; i < 10; i++) {
                    wne.increment();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };

        Runnable r2 = () -> {
            try {
                for (int i = 0; i < 10; i++) {
                    wne.decrement();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };

        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r2);

        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }
}

在上面的代码中,WaitNotifyExample类使用了wait()和notify()方法进行线程间的通信操作。在main()方法中,创建了两个线程t1和t2,分别调用了WaitNotifyExample类中的increment()和decrement()方法。其中,increment()方法会对count进行自增操作;decrement()方法会对count进行自减操作。当count等于5时,increment()方法会调用lock.wait()方法进行等待;当count等于0时,decrement()方法也会调用lock.wait()方法进行等待。在每次increment()或decrement()方法结束时,调用lock.notify()方法唤醒其他等待线程。

通过运行该程序,可以观察到线程之间的通信机制,输出结果应该类似于下面的内容:

Thread 10 incremented count to 1
Thread 11 incremented count to 2
Thread 10 incremented count to 3
Thread 11 incremented count to 4
Thread 10 incremented count to 5
Thread 11 decremented count to 4
Thread 10 decremented count to 3
Thread 11 decremented count to 2
Thread 10 decremented count to 1
Thread 11 decremented count to 0

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java并发编程多线程间的同步控制和通信详解 - Python技术站

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

相关文章

  • 使用.Net实现多线程经验总结

    使用.Net实现多线程是提高程序并发处理能力的一种常用手段。下面将分享我的实战经验总结,并提供两个示例说明。 前置知识 在开始学习.Net多线程前,建议对以下知识有一定的掌握:- C#编程语言- 简单的数据结构和算法- 操作系统原理中进程和线程的概念 多线程设计原则 在多线程编程中,要遵循以下原则,保证程序的正确性和高效性: 避免竞态条件。 多个线程并发执行…

    多线程 2023年5月17日
    00
  • 并发编程之Java内存模型顺序一致性

    Java内存模型顺序一致性 Java内存模型(Java Memory Model,简称JMM)是Java虚拟机规范中的一部分,它定义了Java线程如何与内存交互,以及一个线程在什么情况下才能“看到”另外线程对变量的修改。JMM中定义了一组规则来规范多线程程序的行为,其中之一就是顺序一致性。 顺序一致性 顺序一致性的含义是:如果程序中的某个操作happens-…

    多线程 2023年5月17日
    00
  • 详解C语言编程之thread多线程

    详解C语言编程之thread多线程 什么是多线程编程? 多线程编程是指同时运行多个线程的程序设计,一个进程可包含多个线程,同时执行多个线程可以提升程序的性能和效率。 C语言的多线程实现 C语言的多线程实现一般通过线程库来实现。在Linux下常用的线程库有pthread。Windows下常用的线程库有Win32 API和C++11的thread库。pthrea…

    多线程 2023年5月17日
    00
  • C语言通过案例讲解并发编程模型

    C语言通过案例讲解并发编程模型 什么是并发编程模型? 并发编程模型是指一种应用程序设计的方法,通过该方法,应用程序可以让多个任务并行执行。在并发编程中,任务并不是按顺序依次执行的,而是在同时执行。并发编程旨在提高应用程序的效率,使其可以更快地执行任务。 为什么需要并发编程模型? 现代计算机硬件通常都有多核处理器,这意味着计算机可以同时执行多个任务。如果我们的…

    多线程 2023年5月17日
    00
  • Java多线程之中断线程(Interrupt)的使用详解

    Java多线程之中断线程(Interrupt)的使用详解 在Java中,线程采用协作式多任务处理,即线程必须自主地停止自己或按照其他线程的意愿停止。中断线程是线程之间传递信号的一种机制,允许一个线程打断另一个线程的执行。本文将详细讲解Java多线程之中断线程的使用方法。 中断线程的基本原理以及使用方式 中断线程的本质是给目标线程发出一个中断信号,该信号会将目…

    多线程 2023年5月17日
    00
  • 详解Java并发编程之volatile关键字

    详解Java并发编程之volatile关键字 什么是volatile关键字? volatile 是 Java 中一个非常重要的关键字,用于修饰变量,可以保证多个线程操作同一个变量时的可见性。当一个变量被 volatile 修饰时,线程每次对这个变量进行操作后,都会强制刷新本地缓存,使其他线程可以立即获取到最新的值。 volatile关键字的作用 volati…

    多线程 2023年5月17日
    00
  • Python多线程编程(二):启动线程的两种方法

    文章标题:Python多线程编程(二):启动线程的两种方法 前言 编写多线程程序可以在某种程度上提高程序的并发性和性能,Python提供了多种方式支持多线程编程。本文将着重讲解启动线程的两种方法:继承threading.Thread类和使用函数式API:threading.Thread。 使用继承方式实现启动线程 创建线程方式中,最常见的方法就是继承Thre…

    多线程 2023年5月17日
    00
  • 在IOS中为什么使用多线程及多线程实现的三种方法

    我来为您详细讲解一下在iOS中为什么使用多线程及多线程实现的三种方法。 为什么使用多线程 iOS应用是基于事件驱动的,用户与应用进行交互产生的事件是由主线程处理的。如果我们在主线程中执行一些耗时的操作,比如网络下载或数据处理等,会导致主线程被阻塞,造成应用的卡顿、无响应等不好的用户体验。所以我们需要在iOS中使用多线程。 多线程实现的三种方法 在iOS中,我…

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