最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java synchronized關(guān)鍵字從入門到原理解析

 更新時間:2026年02月24日 09:44:03   作者:百錦再@新空間創(chuàng)想科技  
這篇文章介紹Java synchronized關(guān)鍵字從入門到原理,本課程適合具備Java基礎(chǔ)語法知識,初步了解多線程概念但尚未系統(tǒng)學(xué)習(xí)并發(fā)編程的開發(fā)者,本文結(jié)合實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧

適用對象

本課程適合具備Java基礎(chǔ)語法知識,初步了解多線程概念但尚未系統(tǒng)學(xué)習(xí)并發(fā)編程的開發(fā)者。無論你是準(zhǔn)備面試的求職者,還是希望提升并發(fā)編程能力的工程師,這門課程都將為你打下堅實基礎(chǔ)。

學(xué)習(xí)目標(biāo)

通過兩個課時的系統(tǒng)學(xué)習(xí),你將能夠:

  • 掌握 synchronized的三種使用方式及其區(qū)別
  • 理解 synchronized解決線程安全問題的核心原理
  • 剖析 synchronized底層的Monitor機(jī)制和鎖升級過程
  • 區(qū)分 synchronized與volatile、ReentrantLock的適用場景
  • 應(yīng)對 面試中關(guān)于synchronized的高頻問題

課程安排

  • 第一課時(約40分鐘):基礎(chǔ)概念、使用方式、特性詳解
  • 第二課時(約50分鐘):底層原理、鎖升級機(jī)制、對比與實戰(zhàn)

第一課時:synchronized基礎(chǔ)與使用

1.1 從一個線程安全問題開始

讓我們先看一個經(jīng)典問題:兩個線程同時對共享變量執(zhí)行自增操作。

public class Counter {
    private int count = 0;
    public void increment() {
        count++; // 不是原子操作!
    }
    public int getCount() {
        return count;
    }
}
// 測試代碼
public class Test {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) counter.increment();
        });
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) counter.increment();
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("最終結(jié)果: " + counter.getCount()); // 期望20000,實際小于20000
    }
}

運(yùn)行結(jié)果:多次執(zhí)行,結(jié)果總是小于20000,有時甚至相差甚遠(yuǎn)。

問題根源count++看似一行代碼,但在JVM中分解為三條指令:

  1. 從主內(nèi)存讀取count到工作內(nèi)存(讀)
  2. 對count進(jìn)行加1操作(改)
  3. 將結(jié)果寫回主內(nèi)存(寫)

當(dāng)兩個線程同時執(zhí)行這三步時,可能發(fā)生交替執(zhí)行,導(dǎo)致最后寫入的值覆蓋了之前的計算結(jié)果——這就是典型的競態(tài)條件。

1.2 synchronized是什么?

synchronized是Java提供的一個關(guān)鍵字,譯為“同步”。它可以保證在同一時刻,最多只有一個線程執(zhí)行被它修飾的代碼段,從而解決并發(fā)環(huán)境下的線程安全問題。

從專業(yè)角度說,synchronized實現(xiàn)了互斥訪問,它保證了三個關(guān)鍵特性:

特性說明
原子性被保護(hù)的代碼塊要么全部執(zhí)行,要么完全不執(zhí)行,不會被打斷
可見性一個線程修改共享變量后,其他線程能立即看到最新值
有序性禁止編譯器和處理器對同步塊內(nèi)的代碼進(jìn)行指令重排序

1.3 初識synchronized的三種用法

synchronized的使用非常靈活,可以根據(jù)需要選擇不同的加鎖對象。下面我們通過三個典型場景來理解它們的區(qū)別。

1.3.1 修飾實例方法

public class SyncMethodDemo {
    private int count = 0;
    // synchronized修飾實例方法,鎖是當(dāng)前對象this
    public synchronized void increment() {
        count++;
    }
}

特點

  • 鎖對象是調(diào)用該方法的實例對象(即this)
  • 同一個對象的多個synchronized實例方法,共用同一把鎖
  • 不同對象的方法互不干擾

示意圖

線程A ──> obj1.increment() ──> 獲取obj1鎖 ──> 執(zhí)行
線程B ──> obj1.increment() ──> 等待obj1鎖
線程C ──> obj2.increment() ──> 獲取obj2鎖 ──> 執(zhí)行(與A不沖突)

1.3.2 修飾靜態(tài)方法

public class SyncStaticDemo {
    private static int count = 0;
    // synchronized修飾靜態(tài)方法,鎖是當(dāng)前類的Class對象
    public static synchronized void increment() {
        count++;
    }
}

特點

  • 鎖對象是當(dāng)前類的Class對象(如SyncStaticDemo.class)
  • 所有實例對象共享同一把類鎖
  • 靜態(tài)方法鎖與實例方法鎖互不干擾

思考題:如果一個類既有synchronized靜態(tài)方法,又有synchronized實例方法,兩個線程分別調(diào)用它們,會互斥嗎?

  • 答案:不會。因為一個是類鎖,一個是對象鎖,兩把不同的鎖。

1.3.3 修飾代碼塊

public class SyncBlockDemo {
    private Object lock = new Object();
    private int count = 0;
    public void increment() {
        // 同步代碼塊,鎖是指定的lock對象
        synchronized (lock) {
            count++;
        }
    }
    public void decrement() {
        // 也可以鎖this
        synchronized (this) {
            count--;
        }
    }
}

特點

  • 鎖對象可以任意指定,靈活性最高
  • 可以精確控制同步范圍,提高并發(fā)性能
  • 常用鎖對象:this、自定義鎖對象、類.class

1.4 深入理解鎖的范圍

1.4.1 三種鎖的對比表格

使用形式鎖對象作用范圍典型應(yīng)用場景
修飾實例方法當(dāng)前實例對象單個實例內(nèi)保護(hù)實例變量
修飾靜態(tài)方法當(dāng)前類的Class對象所有實例間保護(hù)靜態(tài)變量
修飾代碼塊指定的任意對象代碼塊內(nèi)細(xì)粒度控制

1.4.2 常見面試題解析

問題1:synchronized修飾代碼塊可以給類加鎖嗎?
當(dāng)然可以!只要在括號內(nèi)傳入類名.class即可。例如:

synchronized (SyncBlockDemo.class) {
    // 這是類鎖
}

問題2:構(gòu)造方法可以用synchronized修飾嗎?
不可以!Java語法規(guī)定構(gòu)造方法不能是同步的。實際上,構(gòu)造方法本身就是線程安全的,因為JVM會保證在對象初始化完成前,其他線程無法訪問該對象。

問題3:靜態(tài)同步方法和非靜態(tài)同步方法同時調(diào)用會互斥嗎?
不會互斥。假設(shè)線程A調(diào)用實例對象的非靜態(tài)同步方法,線程B同時調(diào)用該對象所屬類的靜態(tài)同步方法,它們持有的是兩把不同的鎖(對象鎖 vs 類鎖),因此可以并行執(zhí)行。

1.5 synchronized的核心特性

1.5.1 可重入性

概念:同一個線程在持有鎖的情況下,可以再次獲取同一把鎖,而不會被阻塞。

public class ReentrantDemo {
    public synchronized void methodA() {
        System.out.println("進(jìn)入methodA");
        methodB(); // 直接調(diào)用,不會死鎖
    }
    public synchronized void methodB() {
        System.out.println("進(jìn)入methodB");
    }
}

為什么需要可重入?
如果沒有可重入性,線程在調(diào)用methodA獲取鎖后,調(diào)用methodB時發(fā)現(xiàn)自己還要申請同一把鎖,就會形成死鎖。這顯然不合理。

實現(xiàn)原理:每個鎖關(guān)聯(lián)一個持有線程和一個計數(shù)器。線程第一次獲取鎖時,計數(shù)器置為1;同一線程再次獲取時,計數(shù)器遞增;釋放一次,計數(shù)器遞減。直到計數(shù)器歸零,鎖才真正釋放。

1.5.2 可見性保證

synchronized不僅能保證原子性,還能保證內(nèi)存可見性。JMM(Java內(nèi)存模型)規(guī)定:

  • 線程釋放鎖時,會將工作內(nèi)存中的共享變量刷新到主內(nèi)存
  • 線程獲取鎖時,會清空工作內(nèi)存,從主內(nèi)存重新讀取共享變量

這就確保了:一個線程修改的共享變量,在釋放鎖后,其他線程能立即看到最新值。

1.6 第一課時小結(jié)

  • synchronized是Java內(nèi)置的同步關(guān)鍵字,解決原子性、可見性、有序性問題
  • 三種使用方式:實例方法(鎖this)、靜態(tài)方法(鎖Class對象)、代碼塊(鎖任意對象)
  • 核心特性:可重入性、可見性、互斥性
  • 不同鎖對象決定了不同的同步范圍

第二課時:synchronized原理與優(yōu)化

2.1 從字節(jié)碼看synchronized的本質(zhì)

2.1.1 同步代碼塊的字節(jié)碼

先看一段簡單的同步代碼塊:

public class SyncCodeBlock {
    public void doSomething() {
        synchronized (this) {
            System.out.println("hello");
        }
    }
}

使用javap -c -v反編譯后,關(guān)鍵字節(jié)碼如下:

 3: monitorenter      // 進(jìn)入同步塊,獲取監(jiān)視器鎖
 4: getstatic         // 調(diào)用System.out
 7: ldc               // 加載字符串
 9: invokevirtual     // 調(diào)用println
12: aload_1
13: monitorexit       // 退出同步塊,釋放監(jiān)視器鎖
14: goto 22           // 正常結(jié)束跳轉(zhuǎn)
17: astore_2          // 異常處理開始
18: aload_1
19: monitorexit       // 異常時也釋放鎖
20: aload_2
21: athrow            // 拋出異常
22: return

關(guān)鍵發(fā)現(xiàn)

  • 同步代碼塊使用monitorentermonitorexit指令
  • 有兩個monitorexit:一個正常退出,一個異常退出,確保鎖一定被釋放
  • 這就是為什么synchronized即使拋出異常也不會死鎖

2.1.2 同步方法的字節(jié)碼

public synchronized void syncMethod() {
    System.out.println("hello");
}

反編譯結(jié)果:

public synchronized void syncMethod();
  descriptor: ()V
  flags: ACC_PUBLIC, ACC_SYNCHRONIZED  // 注意這個標(biāo)志
  Code:
   0: getstatic     #2
   3: ldc           #3
   5: invokevirtual #4
   8: return

同步方法沒有monitorenter/monitorexit指令,而是通過方法表flags中的ACC_SYNCHRONIZED標(biāo)識。JVM根據(jù)這個標(biāo)識判斷是否需要獲取鎖。

結(jié)論:兩種實現(xiàn)方式本質(zhì)上都是獲取對象的監(jiān)視器鎖(Monitor Lock),只是表現(xiàn)形式不同。

2.2 Monitor機(jī)制深度剖析

2.2.1 什么是Monitor?

Monitor(監(jiān)視器)是操作系統(tǒng)中用于實現(xiàn)線程同步的機(jī)制。Java中的每個對象都與一個Monitor關(guān)聯(lián),這個關(guān)聯(lián)關(guān)系存儲在對象頭的Mark Word中。

可以把Monitor理解為一個“接待室”,里面有三個關(guān)鍵區(qū)域:

                  ┌─────────────────────┐
                  │      Owner          │ ← 當(dāng)前持有鎖的線程
                  ├─────────────────────┤
                  │     EntryList       │ ← 等待獲取鎖的線程隊列
                  ├─────────────────────┤
                  │     WaitSet         │ ← 調(diào)用了wait()的線程隊列
                  └─────────────────────┘

2.2.2 Monitor的核心數(shù)據(jù)結(jié)構(gòu)

在HotSpot虛擬機(jī)中,Monitor由C++的ObjectMonitor類實現(xiàn),關(guān)鍵字段如下:

字段作用
_owner指向當(dāng)前持有鎖的線程
_EntryList等待獲取鎖的線程隊列
_WaitSet調(diào)用了wait()的線程隊列
_recursions記錄鎖的重入次數(shù)
_count記錄線程獲取鎖的次數(shù)

2.2.3 鎖獲取和釋放的完整流程

以兩個線程T0和T1競爭鎖為例:

步驟1:線程T0嘗試獲取鎖

  • 根據(jù)對象頭找到對應(yīng)的ObjectMonitor
  • 檢查_owner是否為null
  • 通過CAS操作將_owner設(shè)為T0,_count設(shè)為1
  • T0獲取鎖成功,進(jìn)入同步塊執(zhí)行

步驟2:線程T1嘗試獲取鎖

  • 此時_owner為T0,T1 CAS失敗
  • T1會先自旋幾次嘗試(適應(yīng)性自旋)
  • 如果T0很快釋放鎖,T1就成功獲取
  • 如果T0未釋放,T1進(jìn)入_EntryList阻塞等待

步驟3:T0釋放鎖

  • 執(zhí)行monitorexit_count減1
  • _count變?yōu)?,_owner設(shè)為null
  • 喚醒_EntryList中的線程(通常是隊首線程)
  • T1被喚醒,重新競爭鎖

2.3 鎖升級:從偏向鎖到重量級鎖

早期Java的synchronized性能較差,被稱為“重量級鎖”。JDK 1.6之后引入了一系列優(yōu)化,讓synchronized的性能大幅提升。這就是著名的鎖升級機(jī)制。

2.3.1 為什么需要鎖升級?

想象一下這些場景:

  • 場景A:只有一個線程訪問同步代碼,根本不需要鎖競爭
  • 場景B:兩個線程交替訪問,幾乎沒有同時競爭
  • 場景C:多個線程激烈競爭,需要操作系統(tǒng)級別的鎖

如果用重量級鎖統(tǒng)一處理所有場景,場景A和B會造成不必要的性能開銷。鎖升級就是讓synchronized能夠根據(jù)競爭激烈程度,動態(tài)調(diào)整鎖的“重量”。

2.3.2 鎖的四種狀態(tài)

從低到高,鎖有四種狀態(tài):

  1. 無鎖狀態(tài)
  2. 偏向鎖
  3. 輕量級鎖
  4. 重量級鎖

鎖可以升級,但不能降級(除了一次GC清理)。

2.3.3 偏向鎖(Biased Locking)

適用場景:只有一個線程反復(fù)獲取同一把鎖。

原理

  • 第一次獲取鎖時,通過CAS將線程ID記錄到對象頭
  • 之后該線程再來時,只需檢查對象頭中是否是自己ID
  • 如果是,直接進(jìn)入,無需任何同步操作

示例代碼

public class BiasedLockDemo {
    private static List<Integer> list = new Vector<>(); // Vector的方法都是同步的
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            list.add(i); // 同一線程反復(fù)獲取鎖
        }
    }
}

優(yōu)點:幾乎沒有加鎖開銷,性能極高。
缺點:一旦有其他線程嘗試競爭,偏向鎖立即撤銷并升級。

注意:從JDK 15開始,偏向鎖被標(biāo)記為廢棄,未來可能移除。因為在實際應(yīng)用中,它的性能提升有限,且維護(hù)成本高。

2.3.4 輕量級鎖(Lightweight Locking)

適用場景:兩個線程交替執(zhí)行同步塊,沒有真正的競爭。

原理

  • 線程在自己的棧幀中創(chuàng)建Lock Record,存儲對象頭的拷貝
  • 通過CAS嘗試將對象頭指向Lock Record
  • 如果成功,獲取輕量級鎖
  • 如果失敗,說明有競爭,升級為重量級鎖

輕量級鎖的解鎖

  • 通過CAS將對象頭恢復(fù)為原Mark Word
  • 如果恢復(fù)成功,解鎖完成
  • 如果失敗,說明已經(jīng)升級為重量級鎖,走重量級鎖解鎖流程

2.3.5 重量級鎖(Heavyweight Locking)

適用場景:多個線程激烈競爭。

原理

  • 線程進(jìn)入_EntryList隊列阻塞
  • 依賴操作系統(tǒng)Mutex Lock實現(xiàn)
  • 涉及用戶態(tài)和內(nèi)核態(tài)切換,開銷較大

2.3.6 鎖升級流程總結(jié)

                   偏向鎖
                     │
                     │ 有其他線程嘗試獲取
                     ↓
                 輕量級鎖
                     │
                     │ 有真實競爭
                     ↓
                 重量級鎖

2.4 synchronized與volatile的對比

特性synchronizedvolatile
原子性? 保證? 不保證
可見性? 保證? 保證
有序性? 保證? 保證(禁止重排序)
用法修飾方法或代碼塊修飾變量
性能較重(但有優(yōu)化)極輕
適用場景復(fù)合操作單一變量狀態(tài)標(biāo)志

volatile適用示例

public class VolatileDemo {
    private volatile boolean flag = true; // 只作為狀態(tài)標(biāo)志
    public void stop() {
        flag = false; // 簡單寫操作
    }
    public void run() {
        while (flag) {
            // 執(zhí)行任務(wù)
        }
    }
}

2.5 synchronized與ReentrantLock的對比

2.5.1 對比表格

對比維度synchronizedReentrantLock
實現(xiàn)方式JVM關(guān)鍵字Java API(基于AQS)
鎖釋放自動釋放必須手動unlock
公平性非公平可設(shè)置公平/非公平
可中斷不支持支持lockInterruptibly()
超時獲取不支持支持tryLock(timeout)
嘗試獲取不支持支持tryLock()
條件變量一個等待集多個Condition
鎖狀態(tài)查詢不支持支持查詢持有線程等

2.5.2 如何選擇?

優(yōu)先使用synchronized的情況:

  • 同步邏輯簡單,不需要高級功能
  • 希望代碼簡潔不易出錯
  • JVM持續(xù)優(yōu)化,性能已很好

選擇ReentrantLock的情況:

  • 需要公平鎖
  • 需要嘗試獲取鎖或超時獲取
  • 需要可中斷的鎖獲取
  • 需要多個條件變量(如生產(chǎn)者-消費(fèi)者模式)
  • 高競爭場景需要更精細(xì)控制

2.5.3 ReentrantLock使用示例

ReentrantLock lock = new ReentrantLock(true); // 公平鎖
Condition notFull = lock.newCondition();
Condition notEmpty = lock.newCondition();
// 標(biāo)準(zhǔn)使用模式
lock.lock();
try {
    // 臨界區(qū)代碼
    while (條件不滿足) {
        notEmpty.await(); // 等待
    }
    // 執(zhí)行操作
    notFull.signal();
} finally {
    lock.unlock(); // 必須釋放
}

2.6 實戰(zhàn):線程安全的單例模式

綜合運(yùn)用synchronized,實現(xiàn)幾種經(jīng)典的單例模式。

2.6.1 餓漢式(線程安全)

public class EagerSingleton {
    private static final EagerSingleton INSTANCE = new EagerSingleton();
    private EagerSingleton() {}
    public static EagerSingleton getInstance() {
        return INSTANCE;
    }
}

2.6.2 懶漢式(同步方法版)

public class LazySingleton {
    private static LazySingleton instance;
    private LazySingleton() {}
    public static synchronized LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

2.6.3 雙重檢查鎖(DCL)

public class DCLSingleton {
    // volatile保證可見性和禁止重排序
    private static volatile DCLSingleton instance;
    private DCLSingleton() {}
    public static DCLSingleton getInstance() {
        if (instance == null) {
            synchronized (DCLSingleton.class) {
                if (instance == null) {
                    instance = new DCLSingleton();
                }
            }
        }
        return instance;
    }
}

為什么需要volatile?
instance = new DCLSingleton()不是原子操作,可能發(fā)生指令重排序。如果不加volatile,其他線程可能拿到一個未初始化完成的對象。這是DCL的關(guān)鍵細(xì)節(jié)。

2.7 第二課時小結(jié)

  • synchronized底層基于Monitor實現(xiàn),字節(jié)碼層面使用monitorenter/monitorexit或ACC_SYNCHRONIZED
  • 鎖升級機(jī)制(偏向鎖→輕量級鎖→重量級鎖)大幅提升了性能
  • synchronized保證原子性、可見性、有序性,是全面的同步工具
  • 與volatile相比,synchronized更重量但功能更全
  • 與ReentrantLock相比,synchronized簡單易用,ReentrantLock功能更豐富
  • 實際開發(fā)中,根據(jù)場景選擇合適的同步機(jī)制

課程總結(jié)

通過兩個課時的學(xué)習(xí),我們?nèi)嬲莆樟藄ynchronized關(guān)鍵字:

  • 第一課時:從線程安全問題出發(fā),學(xué)習(xí)了synchronized的三種使用方式、鎖的范圍、可重入性等基礎(chǔ)概念
  • 第二課時:深入底層,剖析了Monitor機(jī)制、鎖升級流程,并對比了volatile和ReentrantLock

synchronized作為Java最基礎(chǔ)的同步工具,雖然簡單,但背后的原理并不簡單。理解它的實現(xiàn)機(jī)制,不僅能幫助我們寫出更正確的并發(fā)程序,還能在面試中脫穎而出。

課后思考題

  1. 如果一個線程在同步塊中拋出異常,鎖會自動釋放嗎?為什么?
  2. 偏向鎖在JDK 15中被廢棄的原因是什么?談?wù)勀愕睦斫狻?/li>
  3. 如何用synchronized實現(xiàn)一個阻塞隊列?
  4. 為什么說synchronized是“悲觀鎖”,而CAS是“樂觀鎖”?

到此這篇關(guān)于Java synchronized關(guān)鍵字詳解:從入門到原理(兩課時)的文章就介紹到這了,更多相關(guān)Java synchronized關(guān)鍵字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java線程池的簡單使用方法實例教程

    Java線程池的簡單使用方法實例教程

    線程的使用在java中占有極其重要的地位,在jdk1.4極其之前的jdk版本中,關(guān)于線程池的使用是極其簡陋的,在jdk1.5之后這一情況有了很大的改,這篇文章主要給大家介紹了關(guān)于Java線程池的簡單使用方法,需要的朋友可以參考下
    2021-10-10
  • Java多線程窗口售票問題實例

    Java多線程窗口售票問題實例

    這篇文章主要介紹了Java多線程窗口售票問題實例,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • Spring?boot整合jsp和tiles模板示例

    Spring?boot整合jsp和tiles模板示例

    這篇文章主要介紹了Spring?boot整合jsp模板和tiles模板的示例演示過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • Spring boot如何通過@Scheduled實現(xiàn)定時任務(wù)及多線程配置

    Spring boot如何通過@Scheduled實現(xiàn)定時任務(wù)及多線程配置

    這篇文章主要介紹了Spring boot如何通過@Scheduled實現(xiàn)定時任務(wù)及多線程配置,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12
  • Java實現(xiàn)模擬機(jī)器人對話的示例代碼

    Java實現(xiàn)模擬機(jī)器人對話的示例代碼

    本文主要介紹了Java實現(xiàn)模擬機(jī)器人對話的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • 最新Spring Security的基于內(nèi)存用戶認(rèn)證方式

    最新Spring Security的基于內(nèi)存用戶認(rèn)證方式

    本文講解SpringSecurity內(nèi)存認(rèn)證配置,適用于開發(fā)、測試等場景,通過代碼創(chuàng)建用戶及權(quán)限管理,支持密碼加密,雖簡單但不持久化,生產(chǎn)環(huán)境推薦使用數(shù)據(jù)庫或JWT等認(rèn)證方式,感興趣的朋友一起看看吧
    2025-07-07
  • Java實現(xiàn)在線五子棋對戰(zhàn)游戲(人機(jī)對戰(zhàn))

    Java實現(xiàn)在線五子棋對戰(zhàn)游戲(人機(jī)對戰(zhàn))

    這篇文章主要為大家詳細(xì)介紹了如何利用Java語言實現(xiàn)在線五子棋對戰(zhàn)游戲(人機(jī)對戰(zhàn)),文中的實現(xiàn)步驟講解詳細(xì),感興趣的可以嘗試一下
    2022-09-09
  • JDBC利用C3P0數(shù)據(jù)庫連接池連接數(shù)據(jù)庫

    JDBC利用C3P0數(shù)據(jù)庫連接池連接數(shù)據(jù)庫

    這篇文章主要為大家詳細(xì)介紹了JDBC利用C3P0數(shù)據(jù)庫連接池連接數(shù)據(jù)庫,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • Java Socket+多線程實現(xiàn)多人聊天室功能

    Java Socket+多線程實現(xiàn)多人聊天室功能

    這篇文章主要為大家詳細(xì)介紹了Java Socket+多線程實現(xiàn)多人聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 解讀GC日志中的各項指標(biāo)用法

    解讀GC日志中的各項指標(biāo)用法

    這篇文章主要介紹了GC日志中的各項指標(biāo)用法,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-07-07

最新評論

明水县| 鄢陵县| 和政县| 夏津县| 迭部县| 丰台区| 杭锦后旗| 南澳县| 威宁| 汽车| 五家渠市| 西宁市| 清水县| 兴化市| 彰化县| 陆河县| 罗平县| 甘肃省| 通江县| 唐河县| 保康县| 邓州市| 成武县| 湘潭县| 宁安市| 凌源市| 二连浩特市| 兴海县| 保靖县| 三门县| 阿拉尔市| 牙克石市| 四会市| 二手房| 兴业县| 伊宁县| 荔浦县| 平泉县| 宜都市| 高雄市| 安徽省|