Java实现线程安全的几种方法

网友投稿 896 2022-05-30

我们知道Java有一个特性,多线程,它是一个同时运行多个线程的过程。 当多个线程处理相同的数据,并且我们的数据值发生变化时,这种情况不是线程安全的,我们会得到不一致的结果。 当一个线程已经在一个对象上工作并阻止另一个线程在同一个对象上工作时,这个过程称为线程安全。

在Java中,通过如下方法实现线程安全:

Java中实现线程安全的几种方法

使用线程同步

使用Volatile关键字

使用Atomic变量

使用final关键字

使用线程同步

同步是一次只允许一个线程完成特定任务的过程。 意思是当多个线程同时执行,想要同时访问同一个资源时,就会出现不一致的问题。 因此同步用于通过一次只允许一个线程来解决不一致问题。

同步使用 synchronized 关键字。 Synchronized是作用与同步区域的修饰符。

class A { synchronized void sum(int n) { // Creating a thread instance Thread t = Thread.currentThread(); for (int i = 1; i <= 5; i++) { System.out.println( t.getName() + " : " + (n + i)); } } } // Class B extending thread class class B extends Thread { // Creating an object of class A A a = new A(); public void run() { // Calling sum() method a.sum(10); } } class Test { public static void main(String[] args) { // Creating an object of class B B b = new B(); // Initializing instance t1 of Thread // class with object of class B Thread t1 = new Thread(b); // Initializing instance t2 of Thread // class with object of class B Thread t2 = new Thread(b); // Initializing thread t1 with name //'Thread A' t1.setName("Thread A"); // Initializing thread t2 with name //'Thread B' t2.setName("Thread B"); // Starting thread instance t1 and t2 t1.start(); t2.start(); } }

输出

Thread A : 11 Thread A : 12 Thread A : 13 Thread A : 14 Thread A : 15 Thread B : 11 Thread B : 12 Thread B : 13 Thread B : 14 Thread B : 15

使用Volatile关键字

volatile 关键字是一个字段修饰符,可确保对象可以被多个线程同时使用而不会出现任何问题。 volatile 是确保 Java 程序是线程安全的一种好方法。 volatile 关键字可用作在 Java 中实现线程安全的替代方法。

public class VolatileExample { // Initializing volatile variables // a, b static volatile int a = 0, b = 0; // Defining a static void method static void method_one() { a++; b++; } // Defining static void method static void method_two() { System.out.println( "a=" + a + " b=" + b); } public static void main(String[] args) { // Creating an instance t1 of // Thread class Thread t1 = new Thread() { public void run() { for (int i = 0; i < 5; i++) method_one(); } }; // Creating an instance t2 of // Thread class Thread t2 = new Thread() { public void run() { for (int i = 0; i < 5; i++) method_two(); } }; // Starting instance t1 and t2 t1.start(); t2.start(); } }

输出

a=5 b=5 a=5 b=5 a=5 b=5 a=5 b=5 a=5 b=5

使用Atomic变量

使用原子变量是在 java 中实现线程安全的另一种方法。 当多个线程共享变量时,原子变量确保线程不会相互崩溃。

import java.util.concurrent.atomic.AtomicInteger; class Counter { // Creating a variable of // class type AtomicInteger AtomicInteger count = new AtomicInteger(); // Defining increment() method // to change value of // AtomicInteger variable public void increment() { count.incrementAndGet(); } } public class TestCounter { public static void main( String[] args) throws Exception { // Creating an instance of // Counter class Counter c = new Counter(); // Creating an instance t1 of // Thread class Thread t1 = new Thread( new Runnable() { public void run() { for (int i = 1; i <= 2000; i++) { c.increment(); } } }); // Creating an instance t2 // of Thread class Thread t2 = new Thread( new Runnable() { public void run() { for (int i = 1; i <= 2000; i++) { c.increment(); } } }); // Calling start() method with t1 and t2 t1.start(); t2.start(); // Calling join method with t1 and t2 t1.join(); t2.join(); System.out.println(c.count); } }

输出

4000

使用final关键字

final变量在 java 中也是线程安全的,因为一旦分配了一个对象的某个引用,它就不能指向另一个对象的引用。

public class FinalTest { // Initializing a string // variable of final type final String str = new String("hello"); // Defining a method to // change the value of the final // variable which is not possible, // hence the error will be shown void method() { str = "world"; } }

输出

Compilation Error in java code :- prog.java:14: error: cannot assign a value to final variable str str = "world"; ^ 1 error

Java 任务调度

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:拿走磁盘也甭想读数据——透明加密保安全
下一篇:华为云全球案例故事2020 | 云享·书库 No.5 期推荐(文内含免费下载链接)
相关文章