国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【多線程】線程安全問(wèn)題原因與解決方案

這篇具有很好參考價(jià)值的文章主要介紹了【多線程】線程安全問(wèn)題原因與解決方案。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

目錄

線程安全的概念

線程不安全示例

線程不安全的原因?

? ? 多個(gè)線程修改了同一個(gè)變量

? ? 線程是搶占式執(zhí)行的

? ? 原子性

? ? 內(nèi)存可見(jiàn)性

? ? 有序性

線程不安全解決辦法

?synchronized 關(guān)鍵字-監(jiān)視器鎖monitor lock

? ? synchronized 的特性

????????互斥

????????刷新內(nèi)存

????????可重入

? ? synchronized 使用示例

? ? Java 標(biāo)準(zhǔn)庫(kù)中的線程安全類

volatile 關(guān)鍵字

? ? volatile 能保證內(nèi)存可見(jiàn)性

? ? volatile 不保證原子性

? ? synchronized 也能保證內(nèi)存可見(jiàn)性


線程安全的概念

如果多線程環(huán)境下代碼運(yùn)行的結(jié)果是符合我們預(yù)期的,即在單線程環(huán)境應(yīng)該的結(jié)果,則說(shuō)這個(gè)程序是線 程安全的。

線程不安全示例

public class Insecurity {

    // 定義自增操作的對(duì)象
    private static Counter counter = new Counter();

    public static void main(String[] args) throws InterruptedException {
        // 定義兩個(gè)線程,分別自增5萬(wàn)次
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                counter.increment();
            }
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                counter.increment();
            }
        });

        // 啟動(dòng)線程
        t1.start();
        t2.start();
        // 等待自增完成
        t1.join();
        t2.join();
        // 打印結(jié)果
        System.out.println("count = " + counter.count);

    }
}

class Counter {
    public int count = 0;
    // 自增方法
    public void increment () {
        count++;
    }
}

【多線程】線程安全問(wèn)題原因與解決方案

線程不安全的原因?

? ? 多個(gè)線程修改了同一個(gè)變量

上面的線程不安全的代碼中 , 涉及到多個(gè)線程針對(duì) counter.count 變量進(jìn)行修改。
counter.count 這個(gè)變量就是在堆上. 因此可以被多個(gè)線程共享訪問(wèn).

? ? 線程是搶占式執(zhí)行的

多個(gè)線程在CPU上調(diào)度是隨機(jī)的,順序是不可預(yù)知的。

? ? 原子性

要么都執(zhí)行,要么都不執(zhí)行。

  1. 從內(nèi)存把數(shù)據(jù)讀到 CPU
  2. 進(jìn)行數(shù)據(jù)更新
  3. 把數(shù)據(jù)寫回到 CPU

【多線程】線程安全問(wèn)題原因與解決方案

? ? 內(nèi)存可見(jiàn)性

?可見(jiàn)性指, 一個(gè)線程對(duì)共享變量值的修改,能夠及時(shí)地被其他線程看到.

Java 內(nèi)存模型 (JMM) : Java 虛擬機(jī)規(guī)范中定義了 Java 內(nèi)存模型 .
目的是屏蔽掉各種硬件和操作系統(tǒng)的內(nèi)存訪問(wèn)差異,以實(shí)現(xiàn)讓 Java 程序在各種平臺(tái)下都能達(dá)到一致的并發(fā)效果.

【多線程】線程安全問(wèn)題原因與解決方案

  • 線程之間的共享變量存在 主內(nèi)存 (Main Memory).
  • 每一個(gè)線程都有自己的 "工作內(nèi)存" (Working Memory) .
  • 當(dāng)線程要讀取一個(gè)共享變量的時(shí)候, 會(huì)先把變量從主內(nèi)存拷貝到工作內(nèi)存, 再?gòu)墓ぷ鲀?nèi)存讀取數(shù)據(jù).
  • 當(dāng)線程要修改一個(gè)共享變量的時(shí)候, 也會(huì)先修改工作內(nèi)存中的副本, 再同步回主內(nèi)存.
由于每個(gè)線程有自己的工作內(nèi)存 , 這些工作內(nèi)存中的內(nèi)容相當(dāng)于同一個(gè)共享變量的 " 副本 ". 此時(shí)修改線程1 的工作內(nèi)存中的值 , 線程 2 的工作內(nèi)存不一定會(huì)及時(shí)變化

? ? 有序性

有序性是指編譯過(guò)程中,JVM調(diào)用本地接口,CPU執(zhí)行指令過(guò)程中,指令的有序性。

指令在特殊情況下會(huì)打亂順序,并不是按程序員的預(yù)期去執(zhí)行的。

編譯器對(duì)于指令重排序的前提是 " 保持邏輯不發(fā)生變化 ". 這一點(diǎn)在單線程環(huán)境下比較容易判斷 , 但是在多線程環(huán)境下就沒(méi)那么容易了, 多線程的代碼執(zhí)行復(fù)雜程度更高 , 編譯器很難在編譯階段對(duì)代碼的執(zhí)行效果進(jìn)行預(yù)測(cè), 因此激進(jìn)的重排序很容易導(dǎo)致優(yōu)化后的邏輯和之前不等價(jià) .

線程不安全解決辦法

對(duì)于多線程修改同一個(gè)變量,在真實(shí)業(yè)務(wù)中都是修改同一個(gè)變量,無(wú)法避免。

對(duì)于線程是搶占式執(zhí)行的,CPU調(diào)度是隨機(jī)的,這里CPU是硬件層面,沒(méi)辦法處理。

剩下就是解決其他三個(gè)原因:

public class Main {

    // 定義自增操作的對(duì)象
    private static Counter counter = new Counter();

    public static void main(String[] args) throws InterruptedException {
        // 定義兩個(gè)線程,分別自增5萬(wàn)次
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                counter.increment();
            }
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                counter.increment();
            }
        });

        // 啟動(dòng)線程
        t1.start();
        t2.start();
        // 等待自增完成
        t1.join();
        t2.join();
        // 打印結(jié)果
        System.out.println("count = " + counter.count);

    }
}

class Counter {
    public volatile int count = 0;
    // 自增方法
    public synchronized void increment () {
        count++;
    }
}

【多線程】線程安全問(wèn)題原因與解決方案文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-461668.html

?synchronized 關(guān)鍵字-監(jiān)視器鎖monitor lock

? ? synchronized 的特性

????????互斥

synchronized 會(huì)起到互斥效果 , 某個(gè)線程執(zhí)行到某個(gè)對(duì)象的 synchronized 中時(shí) , 其他線程如果也執(zhí)行到同一個(gè)對(duì)象 synchronized 就會(huì) 阻塞等待
  • 進(jìn)入 synchronized 修飾的代碼塊, 相當(dāng)于 加鎖
  • 退出 synchronized 修飾的代碼塊, 相當(dāng)于 解鎖
synchronized 用的鎖是存在 Java 對(duì)象頭里的。
可以粗略理解成 , 每個(gè)對(duì)象在內(nèi)存中存儲(chǔ)的時(shí)候 , 都存有一塊內(nèi)存表示當(dāng)前的 " 鎖定 " 狀態(tài) ( 類似于廁所的 " 有人 / 無(wú)人 ").
如果當(dāng)前是 " 無(wú)人 " 狀態(tài) , 那么就可以使用 , 使用時(shí)需要設(shè)為 " 有人 " 狀態(tài) .
如果當(dāng)前是 " 有人 " 狀態(tài) , 那么其他人無(wú)法使用 , 只能排隊(duì)
理解 " 阻塞等待 ".
針對(duì)每一把鎖 , 操作系統(tǒng)內(nèi)部都維護(hù)了一個(gè)等待隊(duì)列 . 當(dāng)這個(gè)鎖被某個(gè)線程占有的時(shí)候 , 其他線程嘗試進(jìn)行加鎖, 就加不上了 , 就會(huì)阻塞等待 , 一直等到之前的線程解鎖之后 , 由操作系統(tǒng)喚醒一個(gè)新的線程, 再來(lái)獲取到這個(gè)鎖 .
注意 :
  • 上一個(gè)線程解鎖之后, 下一個(gè)線程并不是立即就能獲取到鎖. 而是要靠操作系統(tǒng)來(lái) "喚醒". 這也就是操作系統(tǒng)線程調(diào)度的一部分工作.
  • 假設(shè)有 A B C 三個(gè)線程, 線程 A 先獲取到鎖, 然后 B 嘗試獲取鎖, 然后 C 再嘗試獲取鎖, 此時(shí) B和 C 都在阻塞隊(duì)列中排隊(duì)等待. 但是當(dāng) A 釋放鎖之后, 雖然 B C 先來(lái)的, 但是 B 不一定就能獲取到鎖, 而是和 C 重新競(jìng)爭(zhēng), 并不遵守先來(lái)后到的規(guī)則.
synchronized 的底層是使用操作系統(tǒng)的 mutex lock 實(shí)現(xiàn)的 .

????????刷新內(nèi)存

synchronized 的工作過(guò)程 :
  1. 獲得互斥鎖
  2. 從主內(nèi)存拷貝變量的最新副本到工作的內(nèi)存
  3. 執(zhí)行代碼
  4. 將更改后的共享變量的值刷新到主內(nèi)存
  5. 釋放互斥鎖
所以 synchronized 也能保證內(nèi)存可見(jiàn)性 . 具體代碼參見(jiàn)后面 volatile 部分 .

????????可重入

synchronized 同步塊對(duì)同一條線程來(lái)說(shuō)是可重入的,不會(huì)出現(xiàn)自己把自己鎖死的問(wèn)題;
理解 " 把自己鎖死 "
一個(gè)線程沒(méi)有釋放鎖 , 然后又嘗試再次加鎖 .
代碼示例
在下面的代碼中 ,
  • increase increase2 兩個(gè)方法都加了 synchronized, 此處的 synchronized 都是針對(duì) this 當(dāng)前對(duì)象加鎖的.
  • 在調(diào)用 increase2 的時(shí)候, 先加了一次鎖, 執(zhí)行到 increase 的時(shí)候, 又加了一次鎖. (上個(gè)鎖還沒(méi)釋放, 相當(dāng)于連續(xù)加兩次鎖)
這個(gè)代碼是完全沒(méi)問(wèn)題的 . 因?yàn)?/span> synchronized 是可重入鎖 .
static class Counter {
 ? ?public int count = 0;
 ? ?synchronized void increase() {
 ? ? ? ?count++;
 ? }
 ? ?synchronized void increase2() {
 ? ? ? ?increase();
 ? }
}
在可重入鎖的內(nèi)部 , 包含了 " 線程持有者 " " 計(jì)數(shù)器 " 兩個(gè)信息 .
  • 如果某個(gè)線程加鎖的時(shí)候, 發(fā)現(xiàn)鎖已經(jīng)被人占用, 但是恰好占用的正是自己, 那么仍然可以繼續(xù)獲取到鎖, 并讓計(jì)數(shù)器自增.
  • 解鎖的時(shí)候計(jì)數(shù)器遞減為 0 的時(shí)候, 才真正釋放鎖. (才能被別的線程獲取到)

? ? synchronized 使用示例

synchronized 本質(zhì)上要修改指定對(duì)象的 " 對(duì)象頭 ". 從使用角度來(lái)看 , synchronized 也勢(shì)必要搭配一個(gè)具體的對(duì)象來(lái)使用.
1) 直接修飾普通方法 : 鎖的 SynchronizedDemo 對(duì)象
public class SynchronizedDemo {
 ? ?public synchronized void methond() {
 ? }
}
2) 修飾靜態(tài)方法 : 鎖的 SynchronizedDemo 類的對(duì)象
public class SynchronizedDemo {
 ? ?public synchronized static void method() {
 ? }
}
3) 修飾代碼塊 : 明確指定鎖哪個(gè)對(duì)象
鎖當(dāng)前對(duì)象
public class SynchronizedDemo {
 ? ?public void method() {
 ? ? ? ?synchronized (this) {
 ? ? ? ? ? ?
 ? ? ? }
 ? }
}
鎖類對(duì)象
public class SynchronizedDemo {
 ? ?public void method() {
 ? ? ? ?synchronized (SynchronizedDemo.class) {
 ? ? ? }
 ? }
}

? ? Java 標(biāo)準(zhǔn)庫(kù)中的線程安全類

Java 標(biāo)準(zhǔn)庫(kù)中很多都是線程不安全的 . 這些類可能會(huì)涉及到多線程修改共享數(shù)據(jù) , 又沒(méi)有任何措施 .
  • ArrayList
  • LinkedList
  • HashMap
  • TreeMap
  • HashSet
  • TreeSet
  • StringBuilder
但是還有一些是線程安全的 . 使用了一些鎖機(jī)制來(lái)控制 .
  • Vector (不推薦使用)
  • HashTable (不推薦使用)
  • ConcurrentHashMap
  • StringBuffer
StringBuffer 的核心方法都帶有 synchronized
還有的雖然沒(méi)有加鎖 , 但是不涉及 " 修改 ", 仍然是線程安全的
  • String

volatile 關(guān)鍵字

? ? volatile 能保證內(nèi)存可見(jiàn)性

volatile 修飾的變量 , 能夠保證 " 內(nèi)存可見(jiàn)性 ".
代碼在寫入 volatile 修飾的變量的時(shí)候 ,
  • 改變線程工作內(nèi)存中volatile變量副本的值
  • 將改變后的副本的值從工作內(nèi)存刷新到主內(nèi)存
代碼在讀取 volatile 修飾的變量的時(shí)候 ,
  • 從主內(nèi)存中讀取volatile變量的最新值到線程的工作內(nèi)存中
  • 從工作內(nèi)存中讀取volatile變量的副本
前面我們討論內(nèi)存可見(jiàn)性時(shí)說(shuō)了 , 直接訪問(wèn)工作內(nèi)存 ( 實(shí)際是 CPU 的寄存器或者 CPU 的緩存 ), 速度非常快, 但是可能出現(xiàn)數(shù)據(jù)不一致的情況 .
加上 volatile , 強(qiáng)制讀寫內(nèi)存 . 速度是慢了 , 但是數(shù)據(jù)變的更準(zhǔn)確了 .
代碼示例
在這個(gè)代碼中
  • 創(chuàng)建兩個(gè)線程 t1 t2
  • t1 中包含一個(gè)循環(huán), 這個(gè)循環(huán)以 flag == 0 為循環(huán)條件.
  • t2 中從鍵盤讀入一個(gè)整數(shù), 并把這個(gè)整數(shù)賦值給 flag.
  • 預(yù)期當(dāng)用戶輸入非 0 的值的時(shí)候, t1 線程結(jié)束.
static class Counter {
 ? ?public int flag = 0;
}
public static void main(String[] args) {
 ? ?Counter counter = new Counter();
 ? ?Thread t1 = new Thread(() -> {
 ? ? ? ?while (counter.flag == 0) {
 ? ? ? ? ? ?// do nothing
 ? ? ? }
 ? ? ? ?System.out.println("循環(huán)結(jié)束!");
 ? });
 ? ?Thread t2 = new Thread(() -> {
 ? ? ? ?Scanner scanner = new Scanner(System.in);
 ? ? ? ?System.out.println("輸入一個(gè)整數(shù):");
 ? ? ? ?counter.flag = scanner.nextInt();
 ? });
 ? ?t1.start();
 ? ?t2.start();
}
// 執(zhí)行效果
// 當(dāng)用戶輸入非0值時(shí), t1 線程循環(huán)不會(huì)結(jié)束. (這顯然是一個(gè) bug)
t1 讀的是自己工作內(nèi)存中的內(nèi)容 .
當(dāng) t2 對(duì) flag 變量進(jìn)行修改 , 此時(shí) t1 感知不到 flag 的變化 .
如果給 flag 加上 volatile
static class Counter {
 ? ?public volatile int flag = 0;
}
// 執(zhí)行效果
// 當(dāng)用戶輸入非0值時(shí), t1 線程循環(huán)能夠立即結(jié)束.

? ? volatile 不保證原子性

volatile synchronized 有著本質(zhì)的區(qū)別 . synchronized 能夠保證原子性 , volatile 保證的是內(nèi)存可見(jiàn)性.
代碼示例
這個(gè)是最初的演示線程安全的代碼 .
  • increase 方法去掉 synchronized
  • count 加上 volatile 關(guān)鍵字.
static class Counter {
 ? ?volatile public int count = 0;
 ? ?void increase() {
 ? ? ? ?count++;
 ? }
}
public static void main(String[] args) throws InterruptedException {
 ? ?final Counter counter = new Counter();
 ? ?Thread t1 = new Thread(() -> {
 ? ? ? ?for (int i = 0; i < 50000; i++) {
 ? ? ? ? ? ?counter.increase();
 ? ? ? }
 ? });
 ? ?Thread t2 = new Thread(() -> {
 ? ? ? ?for (int i = 0; i < 50000; i++) {
 ? ? ? ? ? ?counter.increase();
 ? ? ? }
 ? });
 ? ?t1.start();
 ? ?t2.start();
 ? ?t1.join();
 ? ?t2.join();
 ? ?System.out.println(counter.count);
}
此時(shí)可以看到 , 最終 count 的值仍然無(wú)法保證是 100000.

? ? synchronized 也能保證內(nèi)存可見(jiàn)性

synchronized 既能保證原子性 , 也能保證內(nèi)存可見(jiàn)性 .
對(duì)上面的代碼進(jìn)行調(diào)整 :
  • 去掉 flag volatile
  • t1 的循環(huán)內(nèi)部加上 synchronized, 并借助 counter 對(duì)象加鎖.
static class Counter {
 ? ?public int flag = 0;
}
public static void main(String[] args) {
 ? ?Counter counter = new Counter();
 ? ?Thread t1 = new Thread(() -> {
 ? ? ? ?while (true) {
 ? ? ? ? ? ?synchronized (counter) {
 ? ? ? ? ? ? ? ?if (counter.flag != 0) {
 ? ? ? ? ? ? ? ? ? ?break;
 ? ? ? ? ? ? ? }
 ? ? ? ? ? }
 ? ? ? ? ? ?// do nothing
 ? ? ? }
 ? ? ? ?System.out.println("循環(huán)結(jié)束!");
 ? });
 ? ?Thread t2 = new Thread(() -> {
 ? ? ? ?Scanner scanner = new Scanner(System.in);
 ? ? ? ?System.out.println("輸入一個(gè)整數(shù):");
 ? ? ? ?counter.flag = scanner.nextInt();
 ? });
 ? ?t1.start();
 ? ?t2.start();
}

到了這里,關(guān)于【多線程】線程安全問(wèn)題原因與解決方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 主從同步的延遲問(wèn)題、原因及解決方案

    主從同步的延遲問(wèn)題、原因及解決方案 MySQL的主從同步在實(shí)際使用過(guò)程中會(huì)有從庫(kù)延遲的問(wèn)題,那么為什么會(huì)有這種問(wèn)題呢? 如何避免這種問(wèn)題呢? 情況一: 從服務(wù)器配置過(guò)低導(dǎo)致延遲 這類延遲場(chǎng)景的出現(xiàn)往往是主節(jié)點(diǎn)擁有較大規(guī)格的配置,而只讀節(jié)點(diǎn)卻購(gòu)買了一個(gè)最小規(guī)格的

    2024年02月16日
    瀏覽(24)
  • 從原因到解決方案,深入剖析網(wǎng)絡(luò)錯(cuò)誤問(wèn)題

    從原因到解決方案,深入剖析網(wǎng)絡(luò)錯(cuò)誤問(wèn)題

    當(dāng)計(jì)算機(jī)系統(tǒng)中的客戶端(例如瀏覽器、應(yīng)用程序等)嘗試連接到遠(yuǎn)程服務(wù)器時(shí),網(wǎng)絡(luò)連接錯(cuò)誤是一種常見(jiàn)的問(wèn)題。這種錯(cuò)誤可能會(huì)對(duì)用戶造成很大的困擾,因?yàn)樗赡軐?dǎo)致無(wú)法訪問(wèn)網(wǎng)站或無(wú)法使用某些在線應(yīng)用程序。而網(wǎng)絡(luò)錯(cuò)誤其實(shí)是我們?nèi)粘i_(kāi)發(fā)中很難完全避免掉的一個(gè)

    2024年02月07日
    瀏覽(21)
  • 【多線程基礎(chǔ)】 線程安全及解決方案(看這一篇就夠了)

    【多線程基礎(chǔ)】 線程安全及解決方案(看這一篇就夠了)

    ?????? 點(diǎn)進(jìn)來(lái)你就是我的人了 博主主頁(yè): ??????戳一戳,歡迎大佬指點(diǎn)! 歡迎志同道合的朋友一起加油喔 ?????? 目錄 前言 1. 造成線程不安全的原因有哪些呢? 1.1什么是原子性 1.2什么是內(nèi)存可見(jiàn)性 1.3共享變量可見(jiàn)性實(shí)現(xiàn)的原理 ?1.4 什么是指令重排序 2.解決線程安全

    2024年02月02日
    瀏覽(24)
  • 安卓之導(dǎo)致ANR的原因分析,問(wèn)題定位以及解決方案

    ????????在Android應(yīng)用開(kāi)發(fā)中,Application Not Responding(ANR)是一種常見(jiàn)的性能問(wèn)題,它直接關(guān)系到用戶體驗(yàn)的質(zhì)量。當(dāng)應(yīng)用在特定時(shí)間段內(nèi)無(wú)法及時(shí)響應(yīng)用戶的交互或者系統(tǒng)事件時(shí),系統(tǒng)將會(huì)拋出ANR錯(cuò)誤,提示用戶應(yīng)用已停止響應(yīng)。為了確保應(yīng)用的流暢性和用戶滿意度,理解

    2024年03月13日
    瀏覽(36)
  • 鴻蒙ArkTS Web組件加載空白的問(wèn)題原因及解決方案

    鴻蒙ArkTS Web組件加載空白的問(wèn)題原因及解決方案

    初學(xué)鴻蒙開(kāi)發(fā),按照官方文檔Web組件文檔《使用Web組件加載頁(yè)面》示例中的代碼照抄運(yùn)行后顯示空白,糾結(jié)之余多方搜索后扔無(wú)解決方法。 無(wú)意間gitee搜索鴻蒙web組件項(xiàng)目代碼時(shí)看到 Web組件抽獎(jiǎng)案例(ArkTS) Readme文檔中有一句話,如下: 本篇Codelab使用了在線網(wǎng)頁(yè),需要在配

    2024年02月04日
    瀏覽(75)
  • 電腦啟動(dòng)后出現(xiàn)白屏問(wèn)題的可能原因及解決方案

    電腦開(kāi)機(jī)后出現(xiàn)白屏問(wèn)題是一種常見(jiàn)的故障,可能由多種原因引起。在本文中,我將介紹一些可能的原因,并提供相應(yīng)的解決方案,以幫助您解決這個(gè)問(wèn)題。 顯示器故障:首先,檢查顯示器是否正常工作??梢試L試連接另一個(gè)顯示器或電視,看看是否仍然出現(xiàn)白屏問(wèn)題。如果

    2024年02月04日
    瀏覽(50)
  • Kafka重復(fù)消費(fèi)以及消費(fèi)線程安全關(guān)閉的解決方案

    Kafka消費(fèi)程序每次重啟都會(huì)出現(xiàn)重復(fù)消費(fèi)的情況,考慮是在kill掉程序的時(shí)候,有部分消費(fèi)完的數(shù)據(jù)沒(méi)有提交offsect。 此處表明自動(dòng)提交,即延遲提交(poll的時(shí)候會(huì)根據(jù)配置的自動(dòng)提交時(shí)間間隔去進(jìn)行檢測(cè)并提交)。當(dāng)kill掉程序的時(shí)候,可能消費(fèi)完的數(shù)據(jù)還沒(méi)有到達(dá)提交的時(shí)間

    2024年02月13日
    瀏覽(22)
  • 外部navicat無(wú)法連接mysql數(shù)據(jù)庫(kù)的問(wèn)題原因及解決方案

    外部navicat無(wú)法連接mysql數(shù)據(jù)庫(kù)的問(wèn)題原因及解決方案

    問(wèn)題起因是這樣:在linux操作中的docker中部署了一個(gè)數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)啟動(dòng)之后,端口也映射了(創(chuàng)建容器時(shí)用 -p 30036:3306進(jìn)行的映射),但是在外不想使用navicat連接時(shí),怎么都連不上,本人遇到的問(wèn)題如下 一、端口雖然映射了,但是服務(wù)器上的30036端口并未對(duì)外開(kāi)放,因此要先開(kāi)

    2024年02月07日
    瀏覽(29)
  • Class path contains multiple SLF4J bindings.問(wèn)題原因及解決方案

    問(wèn)題背景 在進(jìn)行l(wèi)ogback的日志輸出測(cè)試時(shí),顯示如下錯(cuò)誤 2、原因 根據(jù)上面的錯(cuò)誤提示,存在多個(gè)SLF4J bindings綁定,即存在多個(gè)slf4j的實(shí)現(xiàn)類,按上圖所示這兩個(gè)實(shí)現(xiàn)分別是 logback-classic-1.2.6和slf4j-log4j12-1.6.1 ,我們需要的是logback而不是log4j, 3、解決方案 因此,我們?nèi)サ鬺og4j的

    2024年02月11日
    瀏覽(22)
  • 【網(wǎng)絡(luò)連接】ping不通的常見(jiàn)原因+解決方案,如何在只能訪問(wèn)網(wǎng)關(guān)時(shí)診斷,并修復(fù)IP不通的問(wèn)題

    【網(wǎng)絡(luò)連接】ping不通的常見(jiàn)原因+解決方案,如何在只能訪問(wèn)網(wǎng)關(guān)時(shí)診斷,并修復(fù)IP不通的問(wèn)題

    ??你好呀!我是 是Yu欸 ?? 2024每日百字篆刻時(shí)光,感謝你的陪伴與支持 ~ ?? 歡迎一起踏上探險(xiǎn)之旅,挖掘無(wú)限可能,共同成長(zhǎng)! 前些天發(fā)現(xiàn)了一個(gè)人工智能學(xué)習(xí)網(wǎng)站,內(nèi)容深入淺出、易于理解。如果對(duì)人工智能感興趣,不妨點(diǎn)擊查看。 粉絲交流貼:網(wǎng)關(guān)能通IP不通可能有

    2024年03月09日
    瀏覽(107)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包