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

yizhihongxing

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中的异常处理是什么?

    Java中的异常处理是指在程序执行过程中出现异常时的机制,通过捕获和处理异常来保证程序在异常情况下正常运行,避免程序崩溃和数据丢失等问题。在Java中,异常是通过Exception类及其派生类的对象来表示的,常见的异常包括NullPointerException、ArrayIndexOutOfBoundsException等。 Java中可以使用try-ca…

    Java 2023年4月27日
    00
  • Java Lambda 表达式详解及示例代码

    Java Lambda 表达式详解及示例代码 1. 什么是 Lambda 表达式 Lambda 表达式是 Java 8 中引入的一个新特性,它可以用更简洁的方式来表示某些接口或抽象类的实现。 Lambda 表达式可以看做是匿名函数,它由三个部分组成:参数列表、箭头符号和函数体。它的基本语法如下: (parameter1, parameter2, …) -…

    Java 2023年5月26日
    00
  • 详解SpringMVC加载配置Properties文件的几种方式

    当我们在SpringMVC项目中需要加载配置文件时,通常会使用Properties文件来存储配置信息。本文将介绍几种在SpringMVC中加载Properties文件的方式。 方式一:使用@PropertySource注解 我们可以使用@PropertySource注解来加载Properties文件。在SpringMVC中,我们可以在配置类中使用该注解来指定…

    Java 2023年5月17日
    00
  • 更简单更高效的Mybatis Plus最新代码生成器AutoGenerator

    下面是“更简单更高效的Mybatis Plus最新代码生成器AutoGenerator”的完整攻略: 什么是Mybatis Plus代码生成器? Mybatis Plus是Mybatis框架的一个增强工具,提供了更多的SQL语句操作方法和强大的代码生成器。Mybatis Plus代码生成器(AutoGenerator)是其中的一个强大的功能,可以帮助我们快速…

    Java 2023年5月20日
    00
  • FckEditor 中文配置手册详细说明

    FckEditor 中文配置手册详细说明 FckEditor 是一个免费的 HTML 编辑器,它具有跨浏览器兼容性和 WYSIWYG(所见即所得)编辑功能。本文将提供 FckEditor 中文配置手册的详细说明,包括安装、配置和使用 FckEditor 的示例。 安装 FckEditor 下载 FckEditor,可以在官方网站(https://ckedit…

    Java 2023年6月15日
    00
  • 利用asp或jsp,flash怎样把数据库中的一张表中的所有记录读取并显示出来

    要利用ASP或JSP,Flash将数据库中的一张表中的所有记录读取并显示出来,需要以下几个步骤: 连接数据库 首先需要先连接数据库。可以使用ASP中的ADODB对象,或JSP中的JDBC驱动来完成数据库连接。连接后,需要指定连接的数据库名称、服务器地址、用户名和密码等信息。 查询数据库 连接成功后,需要使用SQL语句查询数据。可以使用SELECT语句查询数据…

    Java 2023年6月16日
    00
  • 简述Java编程之关系操作符

    在讲解Java编程之关系操作符之前,先来了解一下什么是运算符。 运算符是指用于对一定数据类型的变量进行运算操作的一类特殊字符,可以分为算术运算符、关系运算符、逻辑运算符、位运算符等。 Java编程中的关系运算符主要用于比较两个变量之间的关系,得到的结果是boolean类型,即true或false。在Java中用于关系运算的符号有 ==、!=、>、&lt…

    Java 2023年5月26日
    00
  • 关于Java中对象的向上转型和向下转型

    什么是多态? 同一个类调用同一个方法会产生不同的影响/结果 这就是多态 public class Pet{ public void eat(){ System.out.println(“Pet eat…”) } } class Dog extends Pet{ public void eat(){ System.out.pringln(“Dog eat.…

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