Java多线程 原子性操作类的使用

Java多线程 原子性操作类的使用

在并发编程中,多个线程同时进行操作时,可能会出现线程安全问题。例如两个线程同时对同一个变量进行增加操作,结果可能不是期望的那个。Java提供了原子性操作类来解决这个问题。

原子性操作类

Java原子类是Java编程语言中的一种特殊类,它具有原子性,线程安全性和可比性,并提供了一种简单的基于锁的技术,通过这种技术实现多线程并发访问时变量的安全。

AtomicInteger类的使用

AtomicInteger类提供了原子操作的int型变量,包括增加,减少,增加并赋值,减少并赋值,获取和设置等方法。

示例1

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntegerExample {
    private AtomicInteger count = new AtomicInteger(0);

    public void increment() {
        count.incrementAndGet();
    }

    public int getCount() {
        return count.get();
    }

    public static void main(String[] args) throws InterruptedException {
        AtomicIntegerExample example = new AtomicIntegerExample();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    example.increment();
                }
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    example.increment();
                }
            }
        });

        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();

        System.out.println(example.getCount());
    }
}

示例2

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntegerExample {
    private AtomicInteger count = new AtomicInteger(0);

    public void increment() {
        count.addAndGet(10);
    }

    public int getCount() {
        return count.get();
    }

    public static void main(String[] args) throws InterruptedException {
        AtomicIntegerExample example = new AtomicIntegerExample();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    example.increment();
                }
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    example.increment();
                }
            }
        });

        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();

        System.out.println(example.getCount());
    }
}

AtomicLong类、AtomicBoolean类和AtomicReference类的使用

除了AtomicInteger类外,Java还提供了AtomicLong类,AtomicBoolean类和AtomicReference类。这些类提供了相应的Java基础数据类型的原子操作。

示例3

import java.util.concurrent.atomic.AtomicLong;

public class AtomicLongExample {
    private AtomicLong count = new AtomicLong(0);

    public void increment() {
        count.incrementAndGet();
    }

    public long getCount() {
        return count.get();
    }

    public static void main(String[] args) throws InterruptedException {
        AtomicLongExample example = new AtomicLongExample();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    example.increment();
                }
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    example.increment();
                }
            }
        });

        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();

        System.out.println(example.getCount());
    }
}

示例4

import java.util.concurrent.atomic.AtomicBoolean;

public class AtomicBooleanExample {
    private AtomicBoolean flag = new AtomicBoolean(false);

    public void setFlag() {
        flag.compareAndSet(false, true);
    }

    public boolean getFlag() {
        return flag.get();
    }

    public static void main(String[] args) {
        AtomicBooleanExample example = new AtomicBooleanExample();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                example.setFlag();
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!example.getFlag()) {
                    System.out.println("Flag not set yet.");
                }
                System.out.println("Flag is set.");
            }
        });

        thread1.start();
        thread2.start();
    }
}

示例5

import java.util.concurrent.atomic.AtomicReference;

public class AtomicReferenceExample {
    private AtomicReference<String> name = new AtomicReference<>("");

    public void setName(String name) {
        this.name.compareAndSet("", name);
    }

    public String getName() {
        return name.get();
    }

    public static void main(String[] args) {
        AtomicReferenceExample example = new AtomicReferenceExample();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                example.setName("John");
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (example.getName().equals("")) {
                    System.out.println("Name not set yet.");
                }
                System.out.println("Name is " + example.getName() + ".");
            }
        });

        thread1.start();
        thread2.start();
    }
}

总结

使用Java原子类可以有效地解决多线程并发访问时变量的安全问题。在使用时,应该根据需要选择不同的原子类。需要注意的是,原子操作虽然保证了操作的原子性,但并不一定保证线程安全,具体使用需要谨慎。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程 原子性操作类的使用 - Python技术站

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

相关文章

  • java — 函数式编程

    函数式编程 面向对象过分强调“必须通过对象的形式来做事情”,而函数式思想则尽量忽略面向对象的复杂语法——强调做什么,而不是怎么做。有时只是为了做某事情而不得不创建一个对象,而传递一段代码才是我们真正的目的。 Lambda Lambda是一个匿名函数,可以理解为一段可以传递的代码。当需要启动一个线程去完成任务时, 通常会通过java.lang.Runnable…

    Java 2023年4月22日
    00
  • idea中引入了gb2312编码的文件的解决方法

    下面是关于在IDEA中引入了GB2312编码的文件的解决方法的完整攻略: 标题 首先,需要了解一些关于编码的基础知识。GB2312是一种汉字编码,它包含了常用的中文汉字,但不支持很多生僻字和繁体字。在IDEA中,我们可能需要引入一些使用了GB2312编码的文件,但是默认的编码是UTF-8,如果我们不做任何处理,那么就会出现乱码的情况。接下来就让我们看看具体的…

    Java 2023年5月20日
    00
  • Java的Struts框架报错“ActionMessageException”的原因与解决办法

    当使用Java的Struts框架时,可能会遇到“InvalidUserException”错误。这个错误通常由以下原因之一起: 用户无效:如果用户无效,则可能会出现此错误。在这种情况下,需要检查用户是否有效以解决此问题。 配置错误:如果配置文件中没有正确配置,则可能会现此错误。在这种情况下,检查文件以解决此问题。 以下是两个实例: 例 1 如果用户无效,则可…

    Java 2023年5月5日
    00
  • java Date获取年月日时分秒的实现方法

    获取当前时间 Java中的Date类可以获取当前系统时间,包含年月日时分秒等信息。获取当前时间的代码如下: import java.util.Date; public class DateUtils { public static void main(String[] args) { Date now = new Date(); System.out.pri…

    Java 2023年5月20日
    00
  • Java中JSON处理工具类使用详解

    Java中JSON处理工具类使用详解 什么是JSON JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。JSON格式常…

    Java 2023年5月26日
    00
  • JSP实现简单人事管理系统

    JSP是一种基于Java的Web开发技术,它可以让我们在页面中嵌套Java代码,实现动态生成HTML页面,开发出更加灵活的Web应用程序。在这里,我将详细讲解使用JSP实现简单人事管理系统的完整攻略。下面分为以下步骤: 创建数据库表 创建JavaBean 创建JSP页面 配置Web应用程序 1. 创建数据库表 首先,我们需要创建一个数据库表,用于存储人事管理…

    Java 2023年6月15日
    00
  • Java常用函数式接口总结

    Java常用函数式接口总结 Java已经从JDK 8开始支持函数式编程,因此添加了许多的函数式接口,包括常用的Function、Predicate、Consumer等等。本文将对Java中常用的函数式接口进行总结,并给出相应的使用示例。 Function Function接口定义了一个输入参数类型,返回一个结果类型的方法,通常用于将一个类型的值转换为另一个类…

    Java 2023年5月26日
    00
  • Java中FTPClient上传中文目录、中文文件名乱码问题解决方法

    为了解决Java中FTPClient上传中文目录、中文文件名乱码问题,我们需要进行如下步骤: 步骤一:设置编码格式 Java中的FTPClient默认编码为ISO-8859-1,需要将其改为UTF-8,以支持中文目录和文件名的上传。 FTPClient ftpClient = new FTPClient(); ftpClient.setControlEnco…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部