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小時內刪除侵權內容。