其他修饰符

synchronized 修饰符

1.方法级别的 synchronized

使用synchronized修饰方法,可以确保同一时间只有一个线程能够执行这个方法。这是最简单的同步方式、

public synchronized void synchronizedMethod() {
    // 这个方法是同步的
    // 在方法内的操作是线程安全的
}

2.代码块级别的 synchronized

使用synchronized块,可以指定一个对象(通常是一个共享的锁对象),以确保只有一个线程能够执行包含在 synchronized 块内的代码。它使用了 lockObject 作为锁对象。在进入同步块之前,线程会尝试获取 lockObject 上的锁。如果锁已经被另一个线程占用,那么线程将被阻塞,直到锁被释放。

Object lockObject = new Object(); // 通常用作锁对象

synchronized (lockObject) {
    // 这里的代码是同步的
    // 在代码块内的操作是线程安全的
}

3.实例级别的 synchronized

当多个线程需要同步访问同一个对象的实例方法时,可以使用实例级别的 synchronized。这意味着同一对象的不同方法不能被不同线程同时调用(即标记在类中的函数上而不是类上)

class MyObject {
    public synchronized void synchronizedMethod1() {
        // 这个方法是同步的,只有一个线程能够执行
        // 另一个线程无法同时调用 synchronizedMethod2
    }

    public synchronized void synchronizedMethod2() {
        // 这个方法也是同步的
    }

    public void nonSynchronizedMethod() {
        // 这个方法不是同步的,多个线程可以同时调用
    }
}

4.静态方法的 synchronized

当多个线程需要同步访问同一个类的静态方法时,可以使用静态方法级别的 synchronized。这会锁定整个类而不是实例。(因为这个标记不能标记在类上,只能在静态函数上实现这个效果)

public static synchronized void staticSynchronizedMethod() {
    // 这个静态方法是同步的
}

5.等待-通知机制的 synchronized

synchronized 还用于实现等待-通知机制,允许一个线程等待另一个线程完成某项操作。这通常用于线程间协作的情况,例如生产者-消费者问题。

// 在生产者线程中
synchronized (sharedQueue) {
    // 生产数据
    sharedQueue.notify(); // 通知等待的消费者线程
}

// 在消费者线程中
synchronized (sharedQueue) {
    while (sharedQueue.isEmpty()) {
        sharedQueue.wait(); // 等待生产者通知
    }
    // 消费数据
}

 

transient 修饰符

序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。

该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。

它的主要作用是告诉 Java 序列化机制,在将对象持久化(通常是将对象写入文件或通过网络传输)时,应该忽略带有 transient 修饰符的字段。这意味着这些字段的值不会被保存,也不会被传输。transient 的主要用途包括以下情况:

  1. 安全性:有些字段包含敏感信息,如密码、密钥等,不应该被序列化到外部存储或传输到其他系统。通过将这些字段标记为 transient,可以确保它们在序列化过程中被忽略。

  2. 临时数据:有些字段是暂时性的,不需要持久化。例如,您可能有一个用于缓存计算结果的字段,但这些缓存值不应该被序列化,因为它们可以在反序列化后重新生成。

  3. 不可序列化的字段:有些字段的类型不支持序列化,或者是第三方库的类,不能被序列化。通过将这些字段标记为 transient,可以确保整个对象可以被序列化,而不必考虑这些无法序列化的字段。

volatile 修饰符

volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。

一个 volatile 对象引用可能是 null

public class MyRunnable implements Runnable
{
    private volatile boolean active;
    public void run()
    {
        active = true;
        while (active) // 第一行
        {
            // 代码
        }
    }
    public void stop()
    {
        active = false; // 第二行
    }
}

通常情况下,在一个线程调用 run() 方法(在 Runnable 开启的线程),在另一个线程调用 stop() 方法。 如果 第一行 中缓冲区的 active 值被使用,那么在 第二行 的 active 值为 false 时循环不会停止。

但是以上代码中我们使用了 volatile 修饰 active,所以该循环会停止。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值