欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java在高并發(fā)場(chǎng)景下實(shí)現(xiàn)點(diǎn)贊計(jì)數(shù)器

 更新時(shí)間:2023年06月28日 16:01:57   作者:SSPo  
點(diǎn)贊計(jì)數(shù)器的本質(zhì)就是對(duì)某個(gè)變量在高并發(fā)情況下的修改,這篇文章主要為大家介紹了Java實(shí)現(xiàn)點(diǎn)贊計(jì)數(shù)器的示例代碼,感興趣的小伙伴可以了解一下

點(diǎn)贊計(jì)數(shù)器的本質(zhì)就是對(duì)某個(gè)變量在高并發(fā)情況下的修改,volatile關(guān)鍵字只能保證變量的可見性和有序性,不能保證其原子性

使用方案有如下選擇:

1. Synchronized 關(guān)鍵字

package concurrent;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;
class ClickResource{
    int number = 0;
    public synchronized void clickBySynchronized(){number++;}
}
// 100個(gè)線程, 每個(gè)線程點(diǎn)贊 100萬 次, 求準(zhǔn)確率和效率
public class AccumulatorCompareDemo {
    public static final int _1w = 10000;
    public static final int threadNumber = 100;
    public static void main(String[] args) throws InterruptedException {
        ClickResource clickResource = new ClickResource();
        long startTime  = System.currentTimeMillis();
        CountDownLatch countDownLatch1 = new CountDownLatch(threadNumber);
        for (int i = 0; i < threadNumber; i++) {
            new Thread(()->{
                try {
                    for (int j = 0; j < 100*_1w; j++) {
                        clickResource.clickBySynchronized();
                    }
                }finally {
                    countDownLatch1.countDown();
                }
            },String.valueOf(i)).start();
        }
        countDownLatch1.await();
        long endTime  = System.currentTimeMillis();
        System.out.println("所用時(shí)間="+(endTime-startTime)+"ms"+"    最終點(diǎn)贊次數(shù)="+clickResource.number);
    }
}
// synchronized       悲觀鎖
// 所用時(shí)間=2258ms    最終點(diǎn)贊次數(shù)=100000000

2. 使用 AtomicLong 原子類

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;
class ClickResource{
    int number = 0;
    AtomicLong atomicLong = new AtomicLong(0);
    public void clickByAtomicLong(){atomicLong.getAndIncrement();}
}
// 100個(gè)線程, 每個(gè)線程點(diǎn)贊 100萬 次, 求準(zhǔn)確率和效率
public class AccumulatorCompareDemo {
    public static final int _1w = 10000;
    public static final int threadNumber = 100;
    public static void main(String[] args) throws InterruptedException {
        ClickResource clickResource = new ClickResource();
        long startTime  = System.currentTimeMillis();
        CountDownLatch countDownLatch = new CountDownLatch(threadNumber);
        for (int i = 0; i < threadNumber; i++) {
            new Thread(()->{
                try {
                    for (int j = 0; j < 100*_1w; j++) {
                        clickResource.clickByAtomicLong();
                    }
                }finally {
                    countDownLatch.countDown();
                }
            },String.valueOf(i)).start();
        }
        countDownLatch.await();
        long endTime  = System.currentTimeMillis();
        System.out.println("所用時(shí)間="+(endTime-startTime)+"ms"+"    最終點(diǎn)贊次數(shù)="+clickResource.atomicLong);
    }
}
// CAS - 輕量級(jí)鎖 - 調(diào)用 Unsafe 類的 cas 方法 - 底層操作系統(tǒng)原子指令 
// 所用時(shí)間=1177ms    最終點(diǎn)贊次數(shù)=100000000

3.使用 LongAdder 類

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;
class ClickResource{
    int number = 0;
    LongAdder longAdder = new LongAdder();
    public void clickByLongAdder(){longAdder.increment();}
}
// 100個(gè)線程, 每個(gè)線程點(diǎn)贊 100萬 次, 求準(zhǔn)確率和效率
public class AccumulatorCompareDemo {
    public static final int _1w = 10000;
    public static final int threadNumber = 100;
    public static void main(String[] args) throws InterruptedException {
        ClickResource clickResource = new ClickResource();
        long startTime  = System.currentTimeMillis();
        CountDownLatch countDownLatch = new CountDownLatch(threadNumber);
        CountDownLatch countDownLatch2 = new CountDownLatch(threadNumber);
        CountDownLatch countDownLatch3 = new CountDownLatch(threadNumber);
        CountDownLatch countDownLatch4 = new CountDownLatch(threadNumber);
        for (int i = 0; i < threadNumber; i++) {
            new Thread(()->{
                try {
                    for (int j = 0; j < 100*_1w; j++) {
                        clickResource.clickByLongAdder();
                    }
                }finally {
                    countDownLatch.countDown();
                }
            },String.valueOf(i)).start();
        }
        countDownLatch.await();
        long endTime  = System.currentTimeMillis();
        System.out.println("所用時(shí)間="+(endTime-startTime)+"ms"+"    最終點(diǎn)贊次數(shù)="+clickResource.longAdder);
    }
}
//所用時(shí)間=141ms    最終點(diǎn)贊次數(shù)=100000000

4. 使用 LongAccumulator 類

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;
class ClickResource{
    int number = 0;
    LongAccumulator longAccumulator = new LongAccumulator((x,y)->x+y,0);
    public void clickByLongAccumulator(){longAccumulator.accumulate(1);}
}
// 100個(gè)線程, 每個(gè)線程點(diǎn)贊 100萬 次, 求準(zhǔn)確率和效率
public class AccumulatorCompareDemo {
    public static final int _1w = 10000;
    public static final int threadNumber = 100;
    public static void main(String[] args) throws InterruptedException {
        ClickResource clickResource = new ClickResource();
        long startTime  = System.currentTimeMillis();
        CountDownLatch countDownLatch = new CountDownLatch(threadNumber);
        for (int i = 0; i < threadNumber; i++) {
            new Thread(()->{
                try {
                    for (int j = 0; j < 100*_1w; j++) {
                        clickResource.clickByLongAccumulator();
                    }
                }finally {
                    countDownLatch.countDown();
                }
            },String.valueOf(i)).start();
        }
        countDownLatch.await();
        long endTime  = System.currentTimeMillis();
        System.out.println("所用時(shí)間="+(endTime-startTime)+"ms"+"    最終點(diǎn)贊次數(shù)="+clickResource.longAccumulator);
    }
}
// 所用時(shí)間=150ms    最終點(diǎn)贊次數(shù)=100000000

LongAccumulator 和 LongAdder 底層調(diào)用的方法相同,主要區(qū)別是,LongAdder只能初始為0,且只能做加法操作,LongAccumulator 能初始成任何數(shù)

需要注意的是:

LongAdder 和 LongAccumulator 并不保證最終獲取的數(shù)據(jù)是完全準(zhǔn)確無誤的,也許會(huì)有少許偏差,但在高并發(fā)的點(diǎn)贊場(chǎng)景下犧牲少量的數(shù)據(jù)精確性來保證高性能是完全能接受的

以上就是Java在高并發(fā)場(chǎng)景下實(shí)現(xiàn)點(diǎn)贊計(jì)數(shù)器的詳細(xì)內(nèi)容,更多關(guān)于Java點(diǎn)贊計(jì)數(shù)器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringBoot自定義Starter與自動(dòng)配置實(shí)現(xiàn)方法詳解

    SpringBoot自定義Starter與自動(dòng)配置實(shí)現(xiàn)方法詳解

    在Spring Boot官網(wǎng)為了簡化我們的開發(fā),已經(jīng)提供了非常多場(chǎng)景的Starter來為我們使用,即便如此,也無法全面的滿足我們實(shí)際工作中的開發(fā)場(chǎng)景,這時(shí)我們就需要自定義實(shí)現(xiàn)定制化的Starter
    2023-02-02
  • 通過Maven下載依賴Jar包的流程分享

    通過Maven下載依賴Jar包的流程分享

    本文主要介紹了Maven下載依賴Jar包的詳細(xì)流程,包括輸入Maven倉庫的官方地址、搜索依賴Jar包、選擇版本、復(fù)制和粘貼Maven依賴到pom文件中下載依賴Jar包
    2025-02-02
  • 淺談JavaAPI 中 <E> 與 <T> 的含義

    淺談JavaAPI 中 <E> 與 <T> 的含義

    下面小編就為大家?guī)硪黄獪\談JavaAPI 中 <E> 與 <T> 的含義。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • 聊聊springboot?整合?hbase的問題

    聊聊springboot?整合?hbase的問題

    這篇文章主要介紹了springboot?整合?hbase的問題,文中給大家提到配置linux服務(wù)器hosts及配置window?hosts的相關(guān)知識(shí),需要的朋友可以參考下
    2021-11-11
  • Spring使用@Filter注解創(chuàng)建自定義過濾器

    Spring使用@Filter注解創(chuàng)建自定義過濾器

    Spring 中鮮為人知但非常有用的注解之一是 @Filter,它支持自定義過濾器,下面我們就來深入研究一下如何使用 Spring 的 @Filter 注解來創(chuàng)建自定義過濾器吧
    2023-11-11
  • Java類的加載連接和初始化實(shí)例分析

    Java類的加載連接和初始化實(shí)例分析

    這篇文章主要介紹了Java類的加載連接和初始化,結(jié)合具體實(shí)例形式分析了java類的加載、連接、初始化相關(guān)原理與實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2019-07-07
  • 淺析JAVA中toString方法的作用

    淺析JAVA中toString方法的作用

    以下是對(duì)在JAVA中toString方法的作用進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以參考下
    2013-07-07
  • Java調(diào)用C++程序的實(shí)現(xiàn)方式

    Java調(diào)用C++程序的實(shí)現(xiàn)方式

    這篇文章主要介紹了Java調(diào)用C++程序的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • 解決maven clean報(bào)錯(cuò):Failed to delete xxxxx\target\xxxx.jar

    解決maven clean報(bào)錯(cuò):Failed to delete xxxxx\t

    這篇文章主要介紹了解決maven clean報(bào)錯(cuò):Failed to delete xxxxx\target\xxxx.jar問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Eclipse中引入com.sun.image.codec.jpeg包報(bào)錯(cuò)的完美解決辦法

    Eclipse中引入com.sun.image.codec.jpeg包報(bào)錯(cuò)的完美解決辦法

    Java開發(fā)中對(duì)圖片的操作需要引入 com.sun.image.codec.jpeg,但有時(shí)引入這個(gè)包會(huì)報(bào)錯(cuò),利用下面的操作可以完成解決這個(gè)問題
    2018-02-02

最新評(píng)論