详谈Java多线程的几个常用关键字

接下来我将详细讲解“详谈Java多线程的几个常用关键字”。

一、Java多线程的几个常用关键字

Java中的多线程是通过Thread类及Runnable接口来实现的。在Java多线程中,有几个常用关键字需要熟知,如下所示:

  1. synchronized:用于实现同步,防止并发访问共享数据发生错误,并且保证了多线程的协调运行。

  2. volatile:用于保证可见性和禁止指令重排。

  3. waitnotifynotifyAll:用于实现线程之间的协作。

下面我们详细介绍一下这几个关键字及其使用场景。

二、synchronized关键字

synchronized关键字是Java中实现同步的一种方式。它可以修饰方法或代码块,在多线程中保证线程之间的同步执行,从而防止数据的竞争和错误。

1. synchronized方法

在Java中,使用synchronized关键字修饰的方法称为synchronized方法。当某个线程调用一个synchronized方法时,会自动获取该对象的锁,直到该方法执行完毕后才会自动释放该对象锁。

示例代码:

public class SynchronizedDemo {
    public synchronized void synchronizedMethod() {
        // do something...
    }
}

上面的示例中,我们使用synchronized关键字修饰了synchronizedMethod方法,从而保证该方法在多线程执行时的同步访问。

2. synchronized代码块

synchronized关键字还可以用于修饰代码块,使用synchronized代码块可以精确控制多个线程之间的同步访问。

示例代码:

public class SynchronizedDemo {
    public void synchronizedBlock() {
        synchronized (this) {
            // do something...
        }
    }
}

上面的示例中,我们使用synchronized关键字修饰了代码块,从而控制某段代码在多线程间的同步访问。

三、volatile关键字

volatile关键字与synchronized关键字一样,都是为了多线程的正确执行而设计的。使用volatile关键字可以保证可见性和禁止指令重排。

1. 保证可见性

Java内存模型中的可见性是指,当一个线程修改了共享变量的值时,其他线程能够立即看到修改后的值。使用volatile关键字修饰的变量,可以使该变量的修改对其他线程立即可见。

示例代码:

public class VolatileDemo {
    private volatile int value = 0;

    public void setValue(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public static void main(String[] args) {
        VolatileDemo demo = new VolatileDemo();

        new Thread(() -> {
            demo.setValue(10);
        }).start();

        new Thread(() -> {
            System.out.println(demo.getValue());
        }).start();
    }
}

上面的示例中,我们使用volatile关键字修饰了value变量,从而实现了多个线程之间的可见性。

2. 禁止指令重排

在Java编译器中,为了优化代码运行速度,可能会进行指令重排,即改变指令的顺序,但并不会改变程序的运行结果。但在多线程中,指令重排会导致程序出现难以预料的错误。因此,为了保证多线程执行的正确性,我们需要使用volatile关键字来禁止指令重排。

示例代码:

public class VolatileDemo {
    private static volatile VolatileDemo instance;

    public static VolatileDemo getInstance() {
        if (instance == null) {
            synchronized (VolatileDemo.class) {
                if (instance == null) {
                    instance = new VolatileDemo();
                }
            }
        }
        return instance;
    }
}

上面的示例中,我们使用了volatile关键字来修饰单例模式中的instance变量,从而保证了该变量的可见性和禁止指令重排。

四、wait、notify、notifyAll关键字

在Java中,我们可以使用waitnotifynotifyAll关键字来实现线程间的协作,从而更好地实现多线程的协调运行。

1. wait关键字

wait关键字用于使当前线程等待,直到其他线程调用该对象的notifynotifyAll方法,唤醒当前线程继续执行。

示例代码:

public class WaitNotifyDemo {
    private boolean flag = true;

    public synchronized void printA() {
        while (!flag) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("A");
        flag = false;
        notifyAll();
    }

    public synchronized void printB() {
        while (flag) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("B");
        flag = true;
        notifyAll();
    }

    public static void main(String[] args) {
        WaitNotifyDemo demo = new WaitNotifyDemo();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                demo.printA();
            }
        }).start();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                demo.printB();
            }
        }).start();
    }
}

上面的示例中,我们使用了waitnotifyAll关键字来实现了线程之间的协作,当打印完"A"后,会唤醒其他线程去执行。

2. notify关键字

notify关键字唤醒一个正在等待当前对象锁的线程。如果有多个线程正在等待该对象锁,则只有一个线程会被唤醒。

示例代码:

public class WaitNotifyDemo {
    private Object lock = new Object();

    public void print() {
        synchronized (lock) {
            System.out.println(Thread.currentThread().getName() + " 获取到锁");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.notify();
            System.out.println(Thread.currentThread().getName() + " 唤醒等待线程");
        }
    }

    public static void main(String[] args) {
        WaitNotifyDemo demo = new WaitNotifyDemo();

        new Thread(() -> {
            synchronized (demo.lock) {
                try {
                    System.out.println(Thread.currentThread().getName() + " 等待获取锁");
                    demo.lock.wait();
                    System.out.println(Thread.currentThread().getName() + " 获取到锁");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        new Thread(() -> {
            demo.print();
        }).start();
    }
}

上面的示例中,我们使用了waitnotify关键字来实现了线程之间的协作,当线程1等待获取锁时,线程2获取到锁并执行完毕,然后唤醒线程1继续执行。

3. notifyAll关键字

notifyAll关键字唤醒所有正在等待当前对象锁的线程,让它们去竞争获取对象锁。

示例代码:

public class WaitNotifyDemo {
    private Object lock = new Object();

    public void print() {
        synchronized (lock) {
            System.out.println(Thread.currentThread().getName() + " 获取到锁");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.notifyAll();
            System.out.println(Thread.currentThread().getName() + " 唤醒等待线程");
        }
    }

    public static void main(String[] args) {
        WaitNotifyDemo demo = new WaitNotifyDemo();

        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                synchronized (demo.lock) {
                    try {
                        System.out.println(Thread.currentThread().getName() + " 等待获取锁");
                        demo.lock.wait();
                        System.out.println(Thread.currentThread().getName() + " 获取到锁");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }

        new Thread(() -> {
            demo.print();
        }).start();
    }
}

上面的示例中,我们使用了waitnotifyAll关键字来实现了线程之间的协作,当线程1等待获取锁时,线程2获取到锁并执行完毕,然后唤醒所有等待线程去竞争获取对象锁。

五、总结

Java中的多线程是一种非常重要的技术,其中有几个常用关键字需要熟知,如synchronizedvolatilewaitnotifynotifyAll等。使用这些关键字可以使多线程之间的协调运行更加平稳和有效。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详谈Java多线程的几个常用关键字 - Python技术站

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

相关文章

  • 总结java多线程之互斥与同步解决方案

    这里是关于“总结java多线程之互斥与同步解决方案”的完整攻略。 一、什么是互斥与同步 多线程编程中,访问共享资源可能会导致数据不安全或者结果不一致的情况,因此需要保证多个线程对共享资源的访问是互斥的,同时又能达到协同工作的目的。在 Java 多线程中,提供了两种机制来实现这个目的:互斥和同步。 互斥:指当多个线程同时访问共享资源时,只允许其中的一个线程在访…

    多线程 2023年5月16日
    00
  • Java 中 synchronized的用法详解(四种用法)

    下面是”Java 中 synchronized的用法详解(四种用法)”的完整攻略。 一、synchronized的四个作用 Java中的synchronized关键字可以用于四个方面: 实例方法 静态方法 代码块 class对象锁 二、同步实例方法 用来同步这个实例的所有方法,只允许有一个线程同时访问这个实例的这些方法。需要加在方法前面。 代码示例: pub…

    多线程 2023年5月17日
    00
  • Python 多线程Threading初学教程

    Python 多线程Threading初学教程 简介 在一些需要同时执行多个任务的场景下,使用Python多线程Threading可以有效提高程序的运行效率。本教程将为初学者详细讲解Python多线程的使用方法、常用属性和方法、以及附带两条示例说明。 创建线程 Python多线程的模块是Thread。可以使用该模块中的Thread类来创建线程。Thread中…

    多线程 2023年5月17日
    00
  • SpringCloud LoadBalancerClient 负载均衡原理解析

    SpringCloud LoadBalancerClient 负载均衡原理解析 什么是负载均衡? 负载均衡(Load Balancing)是指将工作请求分担到多个计算资源上进行处理,以达到最优化的资源利用、最大化的吞吐量、最小化响应时间、避免单点故障等目的。 传统的负载均衡方式有硬件负载均衡和软件负载均衡,但这些方式都需要使用专门的设备或者软件,且较为昂贵。…

    多线程 2023年5月17日
    00
  • python单线程下实现多个socket并发过程详解

    本文将为大家详细讲解如何在 Python 单线程下实现多个 socket 并发,具体内容如下: 1. 什么是 socket socket 是计算机上的一个抽象概念,就像打电话需要电话机一样,在网络中发送信息需要由 socket 传递和接收。在 Python 编程语言中,socket 是标准库中用于实现网络通信的一种方式。 2. 单线程下实现多个 socket…

    多线程 2023年5月17日
    00
  • Java多线程之并发编程的基石CAS机制详解

    Java多线程之并发编程的基石CAS机制详解 什么是CAS CAS,即Compare And Swap,中文翻译为比较并交换。是一种无锁算法,用于实现多线程同步。在CAS操作中包含三个操作数:内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在CA…

    多线程 2023年5月16日
    00
  • 浅谈C#多线程简单例子讲解

    下面我来详细讲解“浅谈C#多线程简单例子讲解”的完整攻略。 1. 多线程基础知识 在进行C#多线程编程之前,需要掌握以下基础知识: 线程的定义和生命周期 线程的状态和状态转换 线程同步和互斥 线程池的使用 此外,了解异步编程和并发编程的相关知识也是非常有益的。可以参考官方文档或相关书籍进行学习。 2. 多线程的简单实现 下面我们通过两个简单的例子来介绍C#多…

    多线程 2023年5月17日
    00
  • MySQL多版本并发控制MVCC深入学习

    MySQL多版本并发控制(MVCC)深入学习 介绍 MySQL是最流行的开源关系型数据库之一。在高并发环境下,MySQL 的MVCC(多版本并发控制)是保证数据一致性和性能的重要机制。本文将深入讲解MySQL的MVCC机制,介绍其实现原理和应用场景,并提供实际示例。 MVCC机制概述 MVCC是一种高并发的事务处理机制。实现MVCC的关键是:每个MySQL事…

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