當前位置:首頁 > 公眾號精選 > 架構師社區(qū)
[導讀]前言 話說上回HashMap跟面試官扯了半個小時之后,二面迎來了沒有削弱前的鐘馗,法師的鉤子讓安琪拉有點絕望。鐘馗穿著有些微微泛黃的格子道袍,站在安琪拉對面,開始發(fā)難,其中讓安琪拉印象非常深刻的是法師的synchronized 鉤子。 開場 面試官: ?你先自我介紹


前言

話說上回HashMap跟面試官扯了半個小時之后,二面迎來了沒有削弱前的鐘馗,法師的鉤子讓安琪拉有點絕望。鐘馗穿著有些微微泛黃的格子道袍,站在安琪拉對面,開始發(fā)難,其中讓安琪拉印象非常深刻的是法師的synchronized 鉤子。

開場

面試官:  你先自我介紹一下吧!

安琪拉:  我是安琪拉,草叢三婊之一,最強中單(鐘馗冷哼)!哦,不對,串場了,我是**,目前在--公司做--系統(tǒng)開發(fā)。

面試官:  剛才聽一面的同事說你們上次聊到了synchronized,你借口說要回去補籃,現在能跟我講講了吧?

安琪拉: 【上來就丟鉤子,都不寒暄幾句,問我吃沒吃】嗯嗯,是有聊到 synchronized。

面試官:  那你跟我說說為什么會需要synchronized?什么場景下使用synchronized?

安琪拉:  這個就要說到多線程訪問共享資源了,當一個資源有可能被多個線程同時訪問并修改的話,需要用到,還是畫個圖給您看一下,請看圖:

一個synchronized跟面試官扯了半個小時
在這里插入圖片描述

安琪拉:  如上圖所示,比如在王者榮耀程序中,我們隊有二個線程分別統(tǒng)計后裔和安琪拉的經濟,A線程從內存中read 當前隊伍總經濟加載到線程的本地棧,進行 +100 操作之后,這時候B線程也從內存中取出經濟值 + 200,將200寫回內存,B線程前腳剛寫完,后腳A線程將100 寫回到內存中,就出問題了,我們隊的經濟應該是300, 但是內存中存的卻是100,你說糟不糟心。

面試官:  那你跟我講講用 synchronized 怎么解決這個問題的?

安琪拉:  在訪問競態(tài)資源時加鎖,因為多個線程會修改經濟值,因此經濟值就是靜態(tài)資源,給您show 一下吧?下圖是不加鎖的代碼和控制臺的輸出,請您過目:

二個線程,A線程讓隊伍經濟 +1 ,B線程讓經濟 + 2,分別執(zhí)行一千次,正確的結果應該是3000,結果得到的卻是 2845。

一個synchronized跟面試官扯了半個小時
在這里插入圖片描述

安琪拉:  這個就是加鎖之后的代碼和控制臺的輸出。

一個synchronized跟面試官扯了半個小時
(img-6NwdhDEz-1585279691724)(/Users/zw/Library/Application Support/typora-user-images/image-20200321210555529.png)]

面試官:  我看你用synchronized 鎖住的是代碼塊,synchronized 還有別的作用范圍嗎?

安琪拉:  嗯嗯,synchronized 有以下三種作用范圍:

  1. 在靜態(tài)方法上加鎖;

  2. 在非靜態(tài)方法上加鎖;

  3. 在代碼塊上加鎖;

    示例代碼如下

    public class SynchronizedSample {

    private final Object lock = new Object();

    private static int money = 0;
    //非靜態(tài)方法
    public synchronized void noStaticMethod(){
    money++;
    }
    //靜態(tài)方法
    public static synchronized void staticMethod(){
    money++;
    }

    public void codeBlock(){
    //代碼塊
    synchronized (lock){
    money++;
    }
    }
    }

面試官:  那你了解 synchronized 這三種作用范圍,加鎖方式的區(qū)別嗎?

安琪拉:  了解。首先要明確一點:鎖是加在對象上面的,我們是在對象上加鎖。

重要事情說三遍:在對象上加鎖 ? 3 (這也是為什么wait / notify 需要在鎖定對象后執(zhí)行,只有先拿到鎖才能釋放鎖)

這三種作用范圍的區(qū)別實際是被加鎖的對象的區(qū)別,請看下表:

作用范圍 鎖對象
非靜態(tài)方法 當前對象 => this
靜態(tài)方法 類對象  => SynchronizedSample.class (一切皆對象,這個是類對象)
代碼塊 指定對象 => lock (以上面的代碼為例)

面試官:  那你清楚 JVM 是怎么通過synchronized 在對象上實現加鎖,保證多線程訪問競態(tài)資源安全的嗎?

安琪拉:  【天啦擼, 該來的還是要來】(⊙o⊙)…額,這個說起來有點復雜,我怕時間不夠,要不下次再約?

面試官:  別下次了,今天我有的是時間,你慢慢講,我慢慢你說。

安琪拉:  那要跟您好好說道了。分二個時間段來跟您討論,先說到盤古開天辟地,女媧造石補天,咳咳,不好意思扯遠了。。。。。。

  1. 先說在JDK6 以前,synchronized 那時還屬于重量級鎖,相當于關二爺手中的青龍偃月刀,每次加鎖都依賴操作系統(tǒng)Mutex Lock實現,涉及到操作系統(tǒng)讓線程從用戶態(tài)切換到內核態(tài),切換成本很高;
  2. 到了JDK6,研究人員引入了偏向鎖和輕量級鎖,因為Sun 程序員發(fā)現大部分程序大多數時間都不會發(fā)生多個線程同時訪問競態(tài)資源的情況,每次線程都加鎖解鎖,每次這么搞都要操作系統(tǒng)在用戶態(tài)和內核態(tài)之前來回切,太耗性能了。

面試官:  那你分別跟我講講JDK 6 以前 synchronized為什么這么重?JDK6 之后又是 偏向鎖和輕量級鎖又是怎么回事?

安琪拉:  好的。首先要了解 synchronized 的實現原理,需要理解二個預備知識:

  1. 第一個預備知識:需要知道 Java 對象頭,鎖的類型和狀態(tài)和對象頭的Mark Word息息相關;

    synchronized 鎖 和 對象頭息息相關。我們來看下對象的結構:一個synchronized跟面試官扯了半個小時對象存儲在堆中,主要分為三部分內容,對象頭、對象實例數據和對齊填充(數組對象多一個區(qū)域:記錄數組長度),下面簡單說一下三部分內容,雖然 synchronized 只與對象頭中的 Mard Word相關。

    1. 對象頭:

      對象頭分為二個部分,Mard Word 和 Klass Word,列出了詳細說明:

      對象頭結構 存儲信息-說明
      Mard Word 存儲對象的hashCode、鎖信息或分代年齡或GC標志等信息
      Klass Word 存儲指向對象所屬類(元數據)的指針,JVM通過這個確定這個對象屬于哪個類
    2. 對象實例數據:

      如上圖所示,類中的 成員變量data 就屬于對象實例數據;

    3. 對齊填充:

      JVM要求對象占用的空間必須是8 的倍數,方便內存分配(以字節(jié)為最小單位分配),因此這部分就是用于填滿不夠的空間湊數用的。

  2. 第二個預備知識:需要了解 Monitor ,每個對象都有一個與之關聯的Monitor 對象;Monitor對象屬性如下所示( Hospot 1.7 代碼)  。

    //圖詳細介紹重要變量的作用
    ObjectMonitor() {
    _header = NULL;
    _count = 0; // 重入次數
    _waiters = 0, // 等待線程數
    _recursions = 0;
    _object = NULL;
    _owner = NULL; // 當前持有鎖的線程
    _WaitSet = NULL; // 調用了 wait 方法的線程被阻塞 放置在這里
    _WaitSetLock = 0 ;
    _Responsible = NULL ;
    _succ = NULL ;
    _cxq = NULL ;
    FreeNext = NULL ;
    _EntryList = NULL ; // 等待鎖 處于block的線程 有資格成為候選資源的線程
    _SpinFreq = 0 ;
    _SpinClock = 0 ;
    OwnerIsThread = 0 ;
    }

    對象關聯的 ObjectMonitor 對象有一個線程內部競爭鎖的機制,如下圖所示:一個synchronized跟面試官扯了半個小時

面試官: 預備的二個知識我大體看了,后面給我講講 JDK 6 以前 synchronized具體實現邏輯吧。

安琪拉: 好的?!鹃_始我的表演】

  1. 當有二個線程A、線程B都要開始給我們隊的經濟 money變量 + 錢,要進行操作的時候 ,發(fā)現方法上加了synchronized鎖,這時線程調度到A線程執(zhí)行,A線程就搶先拿到了鎖。拿到鎖的步驟為:- 1.1 將 MonitorObject 中的 _owner設置成 A線程;- 1.2 將 mark word 設置為 Monitor 對象地址,鎖標志位改為10;- 1.3 將B線程阻塞放到 ContentionList 隊列;

  2. JVM 每次從Waiting Queue 的尾部取出一個線程放到OnDeck作為候選者,但是如果并發(fā)比較高,Waiting Queue會被大量線程執(zhí)行CAS操作,為了降低對尾部元素的競爭,將Waiting Queue 拆分成ContentionList 和 EntryList 二個隊列, JVM將一部分線程移到EntryList 作為準備進OnDeck的預備線程。另外說明幾點:

  • 所有請求鎖的線程首先被放在ContentionList這個競爭隊列中;

  • Contention List 中那些有資格成為候選資源的線程被移動到 Entry List 中;

  • 任意時刻,最多只有一個線程正在競爭鎖資源,該線程被成為 OnDeck;

  • 當前已經獲取到所資源的線程被稱為 Owner;

  • 處于 ContentionList、EntryList、WaitSet 中的線程都處于阻塞狀態(tài),該阻塞是由操作系統(tǒng)來完成的(Linux 內核下采用 pthread_mutex_lock 內核函數實現的);

  • 作為Owner 的A 線程執(zhí)行過程中,可能調用wait 釋放鎖,這個時候A線程進入 Wait Set , 等待被喚醒。

  • 以上就是我想說的 synchronized 在 JDK 6之前的實現原理。

    面試官:  那你知道 synchronized 是公平鎖還是非公平鎖嗎?

    安琪拉:  非公平的。主要有以下二點原因:

    • Synchronized 在線程競爭鎖時,首先做的不是直接進ContentionList 隊列排隊,而是嘗試自旋獲取鎖(可能ContentionList 有別的線程在等鎖),如果獲取不到才進入 ContentionList,這明顯對于已經進入隊列的線程是不公平的;
    • 另一個不公平的是自旋獲取鎖的線程還可能直接搶占 OnDeck 線程的鎖資源。

    面試官:  你前面說到 JDK 6 之后synchronized 做了優(yōu)化,跟我講講?

    安琪拉:  不要著急!容我點個治療,再跟你掰扯掰扯。前面說了鎖跟對象頭的 Mark Word 密切相關,我們把目光放到對象頭的 Mark Word 上, Mark Word 存儲結構如下圖和源代碼注釋(以32位JVM為例,后面的討論都基于32位JVM的背景,64位會特殊說明)。Mard Word會在不同的鎖狀態(tài)下,32位指定區(qū)域都有不同的含義,這個是為了節(jié)省存儲空間,用4 字節(jié)就表達了完整的狀態(tài)信息,當然,對象某一時刻只會是下面5 種狀態(tài)種的某一種。

    一個synchronized跟面試官扯了半個小時下面是簡化后的 Mark Word一個synchronized跟面試官扯了半個小時

    hash:保存對象的哈希碼
    age:保存對象的分代年齡
    biased_lock:偏向鎖標識位
    lock:鎖狀態(tài)標識位
    JavaThread*:保存持有偏向鎖的線程ID
    epoch:保存偏向時間戳

    安琪拉:  由于 synchronized 重量級鎖有以下二個問題, 因此JDK 6 之后做了改進,引入了偏向鎖和輕量級鎖:

    • 依賴底層操作系統(tǒng)的 mutex 相關指令實現,加鎖解鎖需要在用戶態(tài)和內核態(tài)之間切換,性能損耗非常明顯。

    • 研究人員發(fā)現,大多數對象的加鎖和解鎖都是在特定的線程中完成。也就是出現線程競爭鎖的情況概率比較低。他們做了一個實驗,找了一些典型的軟件,測試同一個線程加鎖解鎖的重復率,如下圖所示,可以看到重復加鎖比例非常高。早期JVM 有 19% 的執(zhí)行時間浪費在鎖上。

    一個synchronized跟面試官扯了半個小時
    在這里插入圖片描述

    Thin locks are a lot cheaper than inflated locks, but their performance suffers from the fact that every compare-and-swap operation must be executed atomically on multi-processor machines, although most objects are locked and unlocked only by one particular thread.

    It was reported that 19% of the total execution time was wasted by thread synchronization in an early version of Java virtual machine。

    面試官:  你跟我講講 JDK 6 以來 synchronized 鎖狀態(tài)怎么從無鎖狀態(tài)到偏向鎖的嗎?

    安琪拉:  OK的啦!,我們來看下圖對象從無鎖到偏向鎖轉化的過程(JVM -XX:+UseBiasedLocking 開啟偏向鎖):

    一個synchronized跟面試官扯了半個小時
    在這里插入圖片描述
    1. 首先A 線程訪問同步代碼塊,使用CAS 操作將 Thread ID 放到 Mark Word 當中;
    2. 如果CAS 成功,此時線程A 就獲取了鎖
    3. 如果線程CAS 失敗,證明有別的線程持有鎖,例如上圖的線程B 來CAS 就失敗的,這個時候啟動偏向鎖撤銷 (revoke bias);
    4. 鎖撤銷流程:- 讓 A線程在全局安全點阻塞(類似于GC前線程在安全點阻塞) - 遍歷線程棧,查看是否有被鎖對象的鎖記錄( Lock Record),如果有Lock Record,需要修復鎖記錄和Markword,使其變成無鎖狀態(tài)。- 恢復A線程 - 將是否為偏向鎖狀態(tài)置為 0 ,開始進行輕量級加鎖流程 (后面講述) 下圖說明了 Mark Word 在這個過程中的轉化 一個synchronized跟面試官扯了半個小時 面試官:   不錯,那你跟我講講偏向鎖撤銷怎么到輕量級鎖的?還有輕量級鎖什么時候會變成重量級鎖? 安琪拉:   繼續(xù)上面的流程,鎖撤銷之后(偏向鎖狀態(tài)為0),現在無論是A線程還是B線程執(zhí)行到同步代碼塊進行加鎖,流程如下:
    • 線程在自己的棧楨中創(chuàng)建鎖記錄 LockRecord。
    • 線程A 將 Mark Word 拷貝到線程棧的 Lock Record中,這個位置叫 displayced hdr,如下圖所示: 一個synchronized跟面試官扯了半個小時
    • 將鎖記錄中的Owner指針指向加鎖的對象(存放對象地址)。
    • 將鎖對象的對象頭的MarkWord替換為指向鎖記錄的指針。這二步如下圖所示: 一個synchronized跟面試官扯了半個小時
  • 這時鎖標志位變成 00 ,表示輕量級鎖
  • 面試官:  看來對synchronized 很有研究嘛。我鐘馗不信難不倒你,那輕量級鎖什么時候會升級為重量級鎖, 請回答?安琪拉:  當鎖升級為輕量級鎖之后,如果依然有新線程過來競爭鎖,首先新線程會自旋嘗試獲取鎖,嘗試到一定次數(默認10次)依然沒有拿到,鎖就會升級成重量級鎖。面試官:  為什么這么設計?安琪拉:  一般來說,同步代碼塊內的代碼應該很快就執(zhí)行結束,這時候線程B 自旋一段時間是很容易拿到鎖的,但是如果不巧,沒拿到,自旋其實就是死循環(huán),很耗CPU的,因此就直接轉成重量級鎖咯,這樣就不用了線程一直自旋了。這就是鎖膨脹的過程,下圖是Mark Word 和鎖狀態(tài)的轉化圖一個synchronized跟面試官扯了半個小時主要圖我標注出來的,鎖當前為可偏向狀態(tài),偏向鎖狀態(tài)位置就是1,看到很多網上的文章都寫錯了,把這里寫成只有鎖發(fā)生偏向才會置為1,一定要注意。面試官:  既然偏向鎖有撤銷,還會膨脹,性能損耗這么大,還需要用他們呢?安琪拉:  如果確定競態(tài)資源會被高并發(fā)的訪問,建議通過-XX:-UseBiasedLocking 參數關閉偏向鎖,偏向鎖的好處是并發(fā)度很低的情況下,同一個線程獲取鎖不需要內存拷貝的操作,免去了輕量級鎖的在線程棧中建Lock Record,拷貝Mark Down的內容,也免了重量級鎖的底層操作系統(tǒng)用戶態(tài)到內核態(tài)的切換,因為前面說了,需要使用系統(tǒng)指令。另外Hotspot 也做了另一項優(yōu)化,基于鎖對象的epoch 批量偏移和批量撤銷偏移,這樣大大降低了偏向鎖的CAS和鎖撤銷帶來的損耗,圖是研究人員做的壓測:一個synchronized跟面試官扯了半個小時

    Eliminating Synchronization-Related Atomic Operations with Biased Locking and Bulk Rebiasing


    安琪拉:  他們在幾款典型軟件上做了測試,發(fā)現基于epoch 批量撤銷偏向鎖和批量加偏向鎖能大幅提升吞吐量,但是并發(fā)量特別大的時候性能就沒有什么特別的提升了。面試官:可以可以,那你看過synchronized 底層實現源碼沒有?安琪拉:   那當然啦,源碼是我的二技能,高爆發(fā)的傷害能不能打出來就看它了,我們一步一步來。我們把文章開頭的示例代碼編譯成class 文件,然后通過javap -v SynchronizedSample.class  來看下synchronized 到底在源碼層面如何實現的?如下圖所示:一個synchronized跟面試官扯了半個小時安琪拉:  synchronized 在代碼塊上是通過 monitorenter 和 monitorexit指令實現,在靜態(tài)方法和 方法上加鎖是在方法的flags 中加入 ACC_SYNCHRONIZED 。JVM 運行方法時檢查方法的flags,遇到同步標識開始啟動前面的加鎖流程,在方法內部遇到monitorenter指令開始加鎖。

    monitorenter 指令函數源代碼在 InterpreterRuntime::monitorenter

    IRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorenter(JavaThread* thread, BasicObjectLock* elem))
    #ifdef ASSERT
    thread->last_frame().interpreter_frame_verify_monitor(elem);
    #endif
    if (PrintBiasedLockingStatistics) {
    Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
    }
    Handle h_obj(thread, elem->obj());
    assert(Universe::heap()->is_in_reserved_or_null(h_obj()),
    "must be NULL or an object");
    //是否開啟了偏向鎖
    if (UseBiasedLocking) {
    // 嘗試偏向鎖
    ObjectSynchronizer::fast_enter(h_obj, elem->lock(), true, CHECK);
    } else {
    // 輕量鎖邏輯
    ObjectSynchronizer::slow_enter(h_obj, elem->lock(), CHECK);
    }
    assert(Universe::heap()->is_in_reserved_or_null(elem->obj()),
    "must be NULL or an object");
    #ifdef ASSERT
    thread->last_frame().interpreter_frame_verify_monitor(elem);
    #endif
    IRT_END

    偏向鎖代碼

    // -----------------------------------------------------------------------------
    // Fast Monitor Enter/Exit
    // This the fast monitor enter. The interpreter and compiler use
    // some assembly copies of this code. Make sure update those code
    // if the following function is changed. The implementation is
    // extremely sensitive to race condition. Be careful.

    void ObjectSynchronizer::fast_enter(Handle obj, BasicLock* lock, bool attempt_rebias, TRAPS) {
    //是否使用偏向鎖
    if (UseBiasedLocking) {
    // 如果不在全局安全點
    if (!SafepointSynchronize::is_at_safepoint()) {
    // 獲取偏向鎖
    BiasedLocking::Condition cond = BiasedLocking::revoke_and_rebias(obj, attempt_rebias, THREAD);
    if (cond == BiasedLocking::BIAS_REVOKED_AND_REBIASED) {
    return;
    }
    } else {
    assert(!attempt_rebias, "can not rebias toward VM thread");
    // 在全局安全點,撤銷偏向鎖
    BiasedLocking::revoke_at_safepoint(obj);
    }
    assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
    }
    // 進輕量級鎖流程
    slow_enter (obj, lock, THREAD) ;
    }

    偏向鎖的實現具體代碼在 BiasedLocking::revoke_and_rebias 中,因為函數非常長,就不貼出來,有興趣的可以在Hotspot 1.8-biasedLocking.cpp[2]去看。輕量級鎖代碼流程

    void ObjectSynchronizer::slow_enter(Handle obj, BasicLock* lock, TRAPS) {
    //獲取對象的markOop數據mark
    markOop mark = obj->mark();
    assert(!mark->has_bias_pattern(), "should not see bias pattern here");

    //判斷mark是否為無鎖狀態(tài) & 不可偏向(鎖標識為01,偏向鎖標志位為0)
    if (mark->is_neutral()) {
    // Anticipate successful CAS -- the ST of the displaced mark must
    // be visible <= the ST performed by the CAS.
    // 保存Mark 到 線程棧 Lock Record 的displaced_header中
    lock->set_displaced_header(mark);
    // CAS 將 Mark Down 更新為 指向 lock 對象的指針,成功則獲取到鎖
    if (mark == (markOop) Atomic::cmpxchg_ptr(lock, obj()->mark_addr(), mark)) {
    TEVENT (slow_enter: release stacklock) ;
    return ;
    }
    // Fall through to inflate() ...
    } else
    // 根據對象mark 判斷已經有鎖 & mark 中指針指的當前線程的Lock Record(當前線程已經獲取到了,不必重試獲?。?br> if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) {
    assert(lock != mark->locker(), "must not re-lock the same lock");
    assert(lock != (BasicLock*)obj->mark(), "don't relock with same BasicLock");
    lock->set_displaced_header(NULL);
    return;
    }

    lock->set_displaced_header(markOopDesc::unused_mark());
    // 鎖膨脹
    ObjectSynchronizer::inflate(THREAD, obj())->enter(THREAD);

    做個假設,現在線程A 和B 同時執(zhí)行到臨界區(qū)if (mark->is_neutral()):1、線程A和B都把Mark Word復制到各自的_displaced_header字段,該數據保存在線程的棧幀上,是線程私有的;2、Atomic::cmpxchg_ptr 屬于原子操作,保障了只有一個線程可以把Mark Word中替換成指向自己線程棧 displaced_header中的,假設A線程執(zhí)行成功,相當于A獲取到了鎖,開始繼續(xù)執(zhí)行同步代碼塊;3、線程B執(zhí)行失敗,退出臨界區(qū),通過ObjectSynchronizer::inflate方法開始膨脹鎖;

    面試官:synchronized 源碼這部分可以了,不下去了。你跟我講講Java中除了synchronized 還有別的鎖嗎?

    安琪拉:   還有ReentrantLock也可以實現加鎖。

    面試官:那寫段代碼實現之前加經濟的同樣效果。

    安琪拉:   coding  如圖:一個synchronized跟面試官扯了半個小時面試官:哦,那你跟我說說ReentrantLock 的底層實現原理?

    安琪拉:   天色已晚,我們能改日再聊嗎?

    面試官:那你回去等通知吧。

    安琪拉:   【內心是崩潰的】,看來這次面試就黃了,,心累。一個synchronized跟面試官扯了半個小時

    未完,下一篇介紹ReentrantLock相關的底層原理,看安琪拉如何大戰(zhàn)鐘馗面試官三百回合。

    參考資料

    [1]

    一個HashMap跟面試官扯了半個小時: https://blog.csdn.net/zhengwangzw/article/details/104889549

    [2]

    Hotspot 1.8-biasedLocking.cpp: https://github.com/sourcemirror/jdk-8-hotspot/blob/master/src/share/vm/runtime/biasedLocking.cpp

    特別推薦一個分享架構+算法的優(yōu)質內容,還沒關注的小伙伴,可以長按關注一下:

    一個synchronized跟面試官扯了半個小時

    長按訂閱更多精彩▼

    一個synchronized跟面試官扯了半個小時

    如有收獲,點個在看,誠摯感謝

    免責聲明:本文內容由21ic獲得授權后發(fā)布,版權歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯系我們,謝謝!

    本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯系該專欄作者,如若文章內容侵犯您的權益,請及時聯系本站刪除。
    換一批
    延伸閱讀

    9月2日消息,不造車的華為或將催生出更大的獨角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

    關鍵字: 阿維塔 塞力斯 華為

    加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數字化轉型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

    關鍵字: AWS AN BSP 數字化

    倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

    關鍵字: 汽車 人工智能 智能驅動 BSP

    北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

    關鍵字: 亞馬遜 解密 控制平面 BSP

    8月30日消息,據媒體報道,騰訊和網易近期正在縮減他們對日本游戲市場的投資。

    關鍵字: 騰訊 編碼器 CPU

    8月28日消息,今天上午,2024中國國際大數據產業(yè)博覽會開幕式在貴陽舉行,華為董事、質量流程IT總裁陶景文發(fā)表了演講。

    關鍵字: 華為 12nm EDA 半導體

    8月28日消息,在2024中國國際大數據產業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數字世界的話語權最終是由生態(tài)的繁榮決定的。

    關鍵字: 華為 12nm 手機 衛(wèi)星通信

    要點: 有效應對環(huán)境變化,經營業(yè)績穩(wěn)中有升 落實提質增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質量發(fā)展策略,塑強核心競爭優(yōu)勢...

    關鍵字: 通信 BSP 電信運營商 數字經濟

    北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯合牽頭組建的NVI技術創(chuàng)新聯盟在BIRTV2024超高清全產業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現場 NVI技術創(chuàng)新聯...

    關鍵字: VI 傳輸協(xié)議 音頻 BSP

    北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

    關鍵字: BSP 信息技術
    關閉
    關閉