日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

线程安全问题解决

發布時間:2023/12/3 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线程安全问题解决 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

方式一(同步代碼塊)

synchronized(同步監視器){
//需要被同步的代碼
}

說明:1.操作共享數據的代碼,即為需要被同步的代碼。 -->不能包含代碼多了,也不能包含代碼少了。
2.共享數據:多個線程共同操作的變量。比如:ticket就是共享數據。
3.同步監視器,俗稱:鎖。任何一個類的對象,都可以充當鎖。
要求:多個線程必須要共用同一把鎖。
補充:在實現Runnable接口創建多線程的方式中,我們可以考慮使用this充當同步監視器。

package com.atguigu.java;class Window1 implements Runnable{private int ticket = 100; // Object obj = new Object(); // Dog dog = new Dog();@Overridepublic void run() { // Object obj = new Object();while(true){synchronized (this){//此時的this:唯一的Window1的對象 //方式二:synchronized (dog) {if (ticket > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + ":賣票,票號為:" + ticket);ticket--;} else {break;}}}} }public class WindowTest1 {public static void main(String[] args) {Window1 w = new Window1();Thread t1 = new Thread(w);Thread t2 = new Thread(w);Thread t3 = new Thread(w);t1.setName("窗口1");t2.setName("窗口2");t3.setName("窗口3");t1.start();t2.start();t3.start();}}class Dog{} package com.atguigu.java;class Window2 extends Thread{private static int ticket = 100;private static Object obj = new Object();@Overridepublic void run() {while(true){//正確的 // synchronized (obj){synchronized (Window2.class){//Class clazz = Window2.class,Window2.class只會加載一次//錯誤的方式:this代表著t1,t2,t3三個對象 // synchronized (this){if(ticket > 0){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(getName() + ":賣票,票號為:" + ticket);ticket--;}else{break;}}}} }public class WindowTest2 {public static void main(String[] args) {Window2 t1 = new Window2();Window2 t2 = new Window2();Window2 t3 = new Window2();t1.setName("窗口1");t2.setName("窗口2");t3.setName("窗口3");t1.start();t2.start();t3.start();} }

方式二(同步方法)

如果操作共享數據的代碼完整的聲明在一個方法中,我們不妨將此方法聲明同步的。

關于同步方法的總結:

  • 同步方法仍然涉及到同步監視器,只是不需要我們顯式的聲明。
  • 非靜態的同步方法,同步監視器是:this
    靜態的同步方法,同步監視器是:當前類本身
  • package com.atguigu.java;class Window3 implements Runnable {private int ticket = 100;@Overridepublic void run() {while (true) {show();}}private synchronized void show(){//同步監視器:this//synchronized (this){if (ticket > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + ":賣票,票號為:" + ticket);ticket--;}//}} }public class WindowTest3 {public static void main(String[] args) {Window3 w = new Window3();Thread t1 = new Thread(w);Thread t2 = new Thread(w);Thread t3 = new Thread(w);t1.setName("窗口1");t2.setName("窗口2");t3.setName("窗口3");t1.start();t2.start();t3.start();}} package com.atguigu.java;/*** 使用同步方法處理繼承Thread類的方式中的線程安全問題** @author shkstart* @create 2019-02-15 上午 11:43*/ class Window4 extends Thread {private static int ticket = 100;@Overridepublic void run() {while (true) {show();}}private static synchronized void show(){//同步監視器:Window4.class//private synchronized void show(){ //同步監視器:t1,t2,t3。此種解決方式是錯誤的if (ticket > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + ":賣票,票號為:" + ticket);ticket--;}} }public class WindowTest4 {public static void main(String[] args) {Window4 t1 = new Window4();Window4 t2 = new Window4();Window4 t3 = new Window4();t1.setName("窗口1");t2.setName("窗口2");t3.setName("窗口3");t1.start();t2.start();t3.start();} }

    方式三(Lock鎖)—JDK5.0新增

    1. 面試題:synchronizedLock的異同?相同:二者都可以解決線程安全問題不同:synchronized機制在執行完相應的同步代碼以后,自動的釋放同步監視器Lock需要手動的啟動同步(lock()),同時結束同步也需要手動的實現(unlock()2.優先使用順序: Lock 同步代碼塊(已經進入了方法體,分配了相應資源) 同步方法(在方法體之外) package com.atguigu.java1;import java.util.concurrent.locks.ReentrantLock;/*** 解決線程安全問題的方式三:Lock鎖 --- JDK5.0新增** 1. 面試題:synchronized 與 Lock的異同?* 相同:二者都可以解決線程安全問題* 不同:synchronized機制在執行完相應的同步代碼以后,自動的釋放同步監視器* Lock需要手動的啟動同步(lock()),同時結束同步也需要手動的實現(unlock())** 2.優先使用順序:* Lock ? 同步代碼塊(已經進入了方法體,分配了相應資源) ? 同步方法(在方法體之外)*** 面試題:如何解決線程安全問題?有幾種方式* @author shkstart* @create 2019-02-15 下午 3:38*/ class Window implements Runnable{private int ticket = 100;//1.實例化ReentrantLockprivate ReentrantLock lock = new ReentrantLock();@Overridepublic void run() {while(true){try{//2.調用鎖定方法lock()lock.lock();if(ticket > 0){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + ":售票,票號為:" + ticket);ticket--;}else{break;}}finally {//3.調用解鎖方法:unlock()lock.unlock();}}} }public class LockTest {public static void main(String[] args) {Window w = new Window();Thread t1 = new Thread(w);Thread t2 = new Thread(w);Thread t3 = new Thread(w);t1.setName("窗口1");t2.setName("窗口2");t3.setName("窗口3");t1.start();t2.start();t3.start();} }

    總結

    以上是生活随笔為你收集整理的线程安全问题解决的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。