當前位置:首頁 > 公眾號精選 > 小林coding
[導讀]Java的多線程是指程序中包含多個執(zhí)行流,即在一個程序中可以同時運行多個不同的線程來執(zhí)行不同的任務。


0 1
起點



小白,坐在這間屬于華夏國超一流互聯(lián)網(wǎng)公司企鵝巴巴的小會議室里,等著技術面試官的到來。


02
突如其來的面試



Round 1


科學家路人S:

小伙子我看你簡歷上什么也沒寫,這次也是第一面,那我們就隨便問點簡單的多線程問題吧。先說說什么是Java的多線程吧,使用多線程有什么好處?有什么壞處?

小白

媽媽說專家的話不能信!果然,問個多線程還問好處壞處?我不想用不會用能進企鵝巴巴么?

但是作為打工人,我認真的回答道:

Java的多線程是指程序中包含多個執(zhí)行流,即在一個程序中可以同時運行多個不同的線程來執(zhí)行不同的任務。

而使用多線程的好處是可以提高 CPU 的利用率。在多線程程序中,一個線程必須等待的時候,CPU 可以運行其它的線程而不是等待,這樣就大大提高了程序的效率。也就是說允許單個程序創(chuàng)建多個并行執(zhí)行的線程來完成各自的任務。

至于多線程的壞處么,主要有三點。第一點是線程也是程序,所以線程需要占用內(nèi)存,線程越多占用內(nèi)存也越多;第二點是多線程需要協(xié)調(diào)和管理,所以需要 CPU 時間跟蹤線程;最后是線程之間對共享資源的訪問會相互影響,必須解決競用共享資源的問題。


Round 2


科學家路人S繼續(xù)追問:

你剛才講了“并行”這個詞,那你說說并行和并發(fā)有什么區(qū)別?

小白

并發(fā),英文單詞是concurrency,就是多個任務在同一個 CPU 核上,按細分的時間片輪流(交替)執(zhí)行,從邏輯上來看那些任務是同時執(zhí)行。

并行,英文單詞是parallelism,就是單位時間內(nèi),多個處理器或多核處理器同時處理多個任務,是真正意義上的“同時進行”。

這兩句話,我相信99%的同學都知道!但是,如果想進企鵝巴巴,如果想應付P20的科學家!我就一定要自行的結合業(yè)務回答并發(fā)并行的優(yōu)勢!

現(xiàn)在的系統(tǒng)動不動就要求百萬級甚至千萬級的并發(fā)量,而多線程并發(fā)編程正是開發(fā)高并發(fā)系統(tǒng)的基礎,利用好多線程機制可以大大提高系統(tǒng)整體的并發(fā)能力以及性能。面對復雜業(yè)務模型,并行程序會比串行程序更適應業(yè)務需求,而并發(fā)編程更能吻合這種業(yè)務拆分 。


Round 3


路人S和路人B果然都露出了滿意的笑容

路人B開始追問道:

那你說說看,在操作系統(tǒng)中用戶級線程和內(nèi)核級線程是什么?這兩個線程在多核CPU的計算機上是否都能并行?

小白

在操作系統(tǒng)的設計中,為了防止用戶操作敏感指令而對OS帶來安全隱患,我們把OS分成了用戶空間(user space)和內(nèi)核空間(kernel space)。

通過用戶空間的庫類實現(xiàn)的線程,就是用戶級線程(user-level threads,ULT)。這種線程不依賴于操作系統(tǒng)核心,進程利用線程庫提供創(chuàng)建、同步、調(diào)度和管理線程的函數(shù)來控制用戶線程。

說著,我拿了一支筆,畫了這么一張圖:

在圖里,我們可以清楚的看到,線程表(管理線程的數(shù)據(jù)結構)是處于進程內(nèi)部的,完全處于用戶空間層面,內(nèi)核空間對此一無所知!當然,用戶線程也可以沒有線程表!

相應的,由OS內(nèi)核空間直接掌控的線程,稱為內(nèi)核級線程(kernel-level threads,KLT)。其依賴于操作系統(tǒng)核心,由內(nèi)核的內(nèi)部需求進行創(chuàng)建和撤銷。

接著,我畫下了這張圖:

同樣的,在圖中,我們看到內(nèi)核線程的線程表(thread table)位于內(nèi)核中,包括了線程控制塊(TCB),一旦線程阻塞,內(nèi)核會從當前或者其他進程(process)中重新選擇一個線程保證程序的執(zhí)行。

對于用戶級線程來說,其線程的切換發(fā)生在用戶空間,這樣的線程切換至少比陷入內(nèi)核要快一個數(shù)量級。但是該種線程有個嚴重的缺點:如果一個線程開始運行,那么該進程中其他線程就不能運行,除非第一個線程自動放棄CPU。因為在一個單獨的進程內(nèi)部,沒有時鐘中斷,所以不能用輪轉調(diào)度(輪流)的方式調(diào)度線程。

也就是說,同一進程中的用戶級線程,在不考慮調(diào)起多個內(nèi)核級線程的基礎上,是沒有辦法利用多核CPU的,其實質是并發(fā)而非并行。

對于內(nèi)核級線程來說,其線程在內(nèi)核中創(chuàng)建和撤銷線程的開銷比較大,需要考慮上下文切換的開銷。

但是,內(nèi)核級線程是可以利用多核CPU的,即可以并行

這回答的累死我了,不過為了能進企鵝巴巴,走向人生巔峰,一切都值了!


Round 4


路人B點了點頭說:

嗯,小伙子基礎還是比較牢靠的!那你說說Java里的多線程是用戶級線程還是內(nèi)核級線程呢?

小白

是...當我要脫口而出的時候,發(fā)現(xiàn)不對,這面試官在套路我!堂堂科學家,套路還沒入職的孩子么?

Java里的多線程,既不是用戶級線程,也不是內(nèi)核級線程!

首先,Java是跨操作平臺的語言,是使用JVM去運行編譯文件的。不同的JVM對線程的實現(xiàn)不同,相同的JVM對不同操作平臺的線程實現(xiàn)方式也有區(qū)別!

其次,要講明白程序級別實現(xiàn)多線程,就必須先說一下多線程模型。

裂開!怎么感覺這又是一道大題啊!B是操作系統(tǒng)的科學家吧!感覺問的都是很底層的東西了啊,現(xiàn)在程序員內(nèi)卷成這樣了么?實習生都問這么底層的問題了?雖然百般不爽,但是為了拿下美女HR,不!是橫掃offer。我要給路人B講明白這個線程模型!

上面我說過OS上的線程分為ULT和KLT,我們寫程序的代碼只能是在用戶空間里寫代碼!而程序運行中,基本上都會進入內(nèi)核運行,所以我們在實現(xiàn)程序級別多線程的時候,必須讓ULT映射到KLT上去。在程序級別的多線程設計里,有以下三種多線程模型。

多對1模型:在多對一模型中,多個ULT映射到1個KLT上去,此時ULT的進程表處于進程之中。

1對1模型:在一對一模型中,1個ULT對應1個KLT。自己不在進程中創(chuàng)建線程表來管理,幾行代碼之后直接通過系統(tǒng)調(diào)用調(diào)起KLT就能實現(xiàn)。

多對多模型:在多對多模型中,N個ULT對應小于等于N個的KLT。這種模型結合了1對1和多對1的優(yōu)點,用戶創(chuàng)建線程沒有限制,阻塞內(nèi)核系統(tǒng)的命令不會阻塞整個進程。

最后,就拿最熱門的HotSpot VM來說吧,他在Solaris上就有兩種線程實現(xiàn)方式,可以讓用戶選擇一對一或多對多這兩種模型;而在Windows和Linux下,使用的都是一對一的多線程模型,Java的線程通過一一映射到Light Weight Process(輕量級進程,LWP)從而實現(xiàn)了和KLT的一一對應。


Round 5


路人B聽到這個回答,眼睛都亮了!直接追問道:

ULT如何映射到KLT?怎么調(diào)起的?

小白

ULT在執(zhí)行的過程中,如果執(zhí)行的指令需要進入內(nèi)核態(tài),則ULT會通過系統(tǒng)調(diào)用調(diào)起一個KLT!

所謂系統(tǒng)調(diào)度,就是在OS中分割用戶空間和內(nèi)核空間的API。


Round 6


路人B繼續(xù)追問道:

ULT的執(zhí)行過程中可以不調(diào)起KLT么?舉個例子。

小白

可以不調(diào)起,比如ULT中就只有sleep這個指令,就不會進入內(nèi)核態(tài)執(zhí)行,更不會調(diào)起KLT。

問到這里,我有點吐血了都!看著B對我的回答很滿意,我心中卻把B已經(jīng)問候了一百遍!


Round 7


路人S總算接過了話題:

看來同學對于底層的知識理解還湊合,那你有沒有看過HotSpot的源碼?能不能簡單說說看Java的線程是怎么運行的?

小白

這問的還上癮了?P20的問題咋這么“簡單”呢!說實話,自從前幾天發(fā)生了靈異事件之后,我確實技術突飛猛進,這個源代碼我好像還真的瞄了一眼,不過我不能暴露自己擁有金手指的秘密?。?/span>

于是我撓了撓頭,思考了1分鐘,然后說道:

源碼以前看過,只能記得一個大概。

1、在Java中,使用java.lang.Thread的構造方法來構建一個java.lang.Thread對象,此時只是對這個對象的部分字段(例如線程名,優(yōu)先級等)進行初始化;

2、調(diào)用java.lang.Thread對象的start()方法,開始此線程。此時,在start()方法內(nèi)部,調(diào)用start0() 本地方法來開始此線程;

3、start0()在VM中對應的是JVM_StartThread,也就是,在VM中,實際運行的是JVM_StartThread方法(宏),在這個方法中,創(chuàng)建了一個JavaThread對象;

4、在JavaThread對象的創(chuàng)建過程中,會根據(jù)運行平臺創(chuàng)建一個對應的OSThread對象,且JavaThread保持這個OSThread對象的引用;

5、在OSThread對象的創(chuàng)建過程中,創(chuàng)建一個平臺相關的底層級線程,如果這個底層級線程失敗,那么就拋出異常;

6、在正常情況下,這個底層級的線程開始運行,并執(zhí)行java.lang.Thread對象的run方法;

7、當java.lang.Thread生成的Object的run()方法執(zhí)行完畢返回后,或者拋出異常終止后,終止native thread;

8、最后就是釋放相關的資源(包括內(nèi)存、鎖等)

大概就是以上這么個步驟吧。

回答完這個,我要跪謝我的金手指了!我看見路人S在電腦上敲著什么,估計他也比較懵,沒想到我居然能答得上來吧!


Round 8


路人S 對此不置可否,說道:

那你說說什么是上下文切換吧。

小白

多線程編程中一般線程的個數(shù)都大于 CPU 核心的個數(shù),而一個 CPU 核心在任意時刻只能被一個線程使用,為了讓這些線程都能得到有效執(zhí)行,CPU 采取的策略是為每個線程分配時間片并輪轉的形式。

時間片是CPU分配給各個線程的時間,因為時間非常短,所以CPU不斷通過切換線程,讓我們覺得多個線程是同時執(zhí)行的,時間片一般是幾十毫秒。

當一個線程的時間片用完的時候就會重新處于就緒狀態(tài)讓給其他線程使用,這個過程就屬于一次上下文切換。

概括來說就是:當前任務在執(zhí)行完 CPU 時間片切換到另一個任務之前會先保存自己的狀態(tài),以便下次再切換回這個任務時,可以再加載這個任務的狀態(tài)。任務從保存到再加載的過程就是一次上下文切換。


Round 9


路人S繼續(xù)問道:

頻繁切換上下文會有什么問題?

小白

上下文切換通常是計算密集型的,每次切換時,需要保存當前的狀態(tài)起來,以便能夠進行恢復先前狀態(tài),而這個切換時非常損耗性能。

也就是說,它需要相當可觀的處理器時間,在每秒幾十上百次的切換中,每次切換都需要納秒量級的時間。所以,上下文切換對系統(tǒng)來說意味著消耗大量的 CPU 時間,事實上,可能是操作系統(tǒng)中時間消耗最大的操作。

Linux 相比與其他操作系統(tǒng)(包括其他類 Unix 系統(tǒng))有很多的優(yōu)點,其中有一項就是,其上下文切換和模式切換的時間消耗非常少。


Round 10


S繼續(xù)問:

減少上下文切換的方式有哪些?

小白

通常減少上下文切換的方式有:

1、無鎖并發(fā)編程:可以參照concurrentHashMap鎖分段的思想,不同的線程處理不同段的數(shù)據(jù),這樣在多線程競爭的條件下,可以減少上下文切換的時間。

2、CAS算法:利用Atomic下使用CAS算法來更新數(shù)據(jù),使用了樂觀鎖,可以有效的減少一部分不必要的鎖競爭帶來的上下文切換。

3、使用最少線程:避免創(chuàng)建不需要的線程,比如任務很少,但是創(chuàng)建了很多的線程,這樣會造成大量的線程都處于等待狀態(tài)。

4、協(xié)程:在單線程里實現(xiàn)多任務的調(diào)度,并在單線程里維持多個任務間的切換。


Round 11


路人B聽了,眼睛一亮,立刻追問道:

協(xié)程是什么?和用戶線程有什么區(qū)別?

小白

我聽了真想抽自己幾個嘴巴子,怎么又來了!B是只會OS吧!

協(xié)程的英文單詞是Coroutine,這是一個程序組件,它既不是線程也不是進程。它的執(zhí)行過程更類似于一個方法,或者說不帶返回值的函數(shù)調(diào)用。

我看到過stack overflow和很多博客里,都認為這兩者是一個東西。但是,在我的理解中,這兩者還是有區(qū)別的。

不可否認的是,協(xié)程和ULT做的是同一個事情。所以從某種角度上講,他們確實是等價的!

但是,ULT這個概念被提出的時候,其背后的思想本質是講ULT是個本機線程,也就是使用了OS的用戶空間內(nèi)提供的庫類直接創(chuàng)建的線程。這個時候,你不需要在OS上面添加一些其他第三方的庫類。

而協(xié)程這個概念是康威定律的提出者Melvin Edward Conway在1958年提出的一個概念,其背后的思想是不直接使用OS本身的庫類,自己做一些庫類去實現(xiàn)并發(fā)。在那個年代,OS上面的第三方庫類并不像現(xiàn)在這么流行,OS本身的庫類和其他第三方庫類的結合也并不像今天這么容易。所以協(xié)程并不是本機線程,他是需要借助一些其他不屬于OS的第三方庫類調(diào)用OS用戶空間的庫類來實現(xiàn)達到ULT的效果。

當然,這個概念在今天來看,就會顯得很讓人混淆了。因為到底哪些庫類算是OS本機的庫類,哪些算是第三方庫類?這和1960年的時候已經(jīng)有絕大的區(qū)別了!所以大家認為這兩者是一個東西,其實也不能說他說的不對,只能說可能對這個思想本身背后代表的東西不明白。


Round 12


路人B聽了,立刻坐直了身體,繼續(xù)追問道:

那你知道fiber么?這個和上面兩個名詞有什么區(qū)別?

小白

fiber也是一種本機線程,其本質是一種特殊的ULT,即更輕量級的ULT。說白了就是這種ULT的線程表一定存于進程之中。

而我們在構建一對一多線程模型的時候,ULT的線程表其實還是交給內(nèi)核了!這是兩者之間最直接的差別。所以我們經(jīng)常稱fiber就是協(xié)同調(diào)度的ULT,在win32中可以調(diào)用fiber來構建多對多的多線程模型。

其實,fiber、coroutine和ULT在用戶層面能看到的效果是基本等價的。

其中ULT是描述OS庫本身提供的功能;fiber描述的是OS提供的協(xié)同調(diào)度的ULT;coroutine描述的是第三方實現(xiàn)的并發(fā)并行功能。

這些名詞很多都是歷史原因的問題,同時也是深入研究需要了解的事情,我們普通程序員在使用的時候,更多的關心的是應用層方面的東西。而這些名詞的理解已經(jīng)深入到源碼層了。


Round 13


路人S估計被我秀的腦殼痛了,立刻說道:

還是講講看在 Java 程序中怎么保證多線程的運行安全吧。

小白

Java的線程安全在三個方面體現(xiàn):

原子性:提供互斥訪問,同一時刻只能有一個線程對數(shù)據(jù)進行操作,在Java中使用了atomic和synchronized這兩個關鍵字來確保原子性;

可見性:一個線程對主內(nèi)存的修改可以及時地被其他線程看到,在Java中使用了synchronized和volatile這兩個關鍵字確??梢娦裕?/span>

有序性:一個線程觀察其他線程中的指令執(zhí)行順序,由于指令重排序,該觀察結果一般雜亂無序,在Java中使用了happens-before原則來確保有序性。


Round 14


路人S 繼續(xù)問道:

你剛才講了有序性,那你說說代碼為什么會重排序?

小白

在執(zhí)行程序時,為了提高性能,處理器和編譯器常常會對指令進行重排序。


Round 15


路人S繼續(xù)追問:

重排序是想怎么重排就重排么?

小白

這面試官也很難纏啊,怎么一直在追問,是需要我給他孝敬一根華子么?要不是看著旁邊有個美女HR,我早就孝敬S他老人家了!

當然不是!不能隨意重排序,不是你想怎么排序就怎么排序,它需要滿足以下兩個條件:

1、在單線程環(huán)境下不能改變程序運行的結果;

2、存在數(shù)據(jù)依賴關系的不允許重排序。

所以重排序不會對單線程有影響,只會破壞多線程的執(zhí)行語義。


Round 16


路人S繼續(xù)追問道:

那你講講看在Java中如何保障重排序不影響單線程的吧。

小白

保障這一結果是因為在編譯器,runtime 和處理器都必須遵守as-if-serial語義規(guī)則。

為了遵守as-if-serial語義,編譯器和處理器不會對存在數(shù)據(jù)依賴關系的操作做重排序,因為這種重排序會改變執(zhí)行結果。但是,如果操作之間不存在數(shù)據(jù)依賴關系,這些操作可能被編譯器和處理器重排序。

我來舉個例子吧

說著我拿著筆在紙上寫了三行簡單的代碼:

我們看這個例子,A和C之間存在數(shù)據(jù)依賴關系,同時B和C之間也存在數(shù)據(jù)依賴關系。因此在最終執(zhí)行的指令序列中,C不能被重排序到A和B的前面,如果C排到A和B的前面,那么程序的結果將會被改變。但A和B之間沒有數(shù)據(jù)依賴關系,編譯器和處理器可以重排序A和B之間的執(zhí)行順序。

這就是as-if-serial語義。


Round 17


路人S繼續(xù)問道:

那你說說看你剛才講的happens-before原則吧。

小白

happens-before說白了就是誰在誰前面發(fā)生的一個關系。

HB規(guī)則是Java內(nèi)存模型(JMM)向程序員提供的跨線程內(nèi)存可見性保證。

說的直白一點,就是如果A線程的寫操作a與B線程的讀操作b之間存在happens-before關系,盡管a操作和b操作在不同的線程中執(zhí)行,但JMM向程序員保證a操作將對b操作可見。

具體的定義為:

1、如果一個操作happens-before另一個操作,那么第一個操作的執(zhí)行結果將對第二個操作可見,而且第一個操作的執(zhí)行順序排在第二個操作之前。

2、兩個操作之間存在happens-before關系,并不意味著Java平臺的具體實現(xiàn)必須要按照happens-before關系指定的順序來執(zhí)行。如果重排序之后的執(zhí)行結果,與按happens-before關系來執(zhí)行的結果一致,那么這種重排序并不非法。

具體的規(guī)則有8條:

1、程序順序規(guī)則:一個線程中的每個操作,happens-before于該線程中的任意后續(xù)操作。

2、監(jiān)視器鎖規(guī)則:對一個鎖的解鎖,happens-before于隨后對這個鎖的加鎖。

3、volatile變量規(guī)則:對一個volatile域的寫,happens-before于任意后續(xù)對這個volatile域的讀。

4、傳遞性:如果A happens-before B,且B happens-before C,那么A happens-before C。

5、start()規(guī)則:如果線程A執(zhí)行操作ThreadB.start()(啟動線程B),那么A線程的ThreadB.start()操作happens-before于線程B中的任意操作。

6、Join()規(guī)則:如果線程A執(zhí)行操作ThreadB.join()并成功返回,那么線程B中的任意操作happens-before于線程A從ThreadB.join()操作成功返回。

7、程序中斷規(guī)則:對線程interrupted()方法的調(diào)用先行于被中斷線程的代碼檢測到中斷時間的發(fā)生。

8、對象finalize規(guī)則:一個對象的初始化完成(構造函數(shù)執(zhí)行結束)先行于發(fā)生它的finalize()方法的開始。


Round 18


路人S接著追問:

你剛才說HB規(guī)則不代表最終的執(zhí)行順序,能不能舉個例子。

小白

就拿講as-if-serial提到的例子舉例吧,例子很簡單就是面積=寬*高。

利用HB的程序順序規(guī)則,存在三個happens-before關系:

1、A happens-before B;

2、B happens-before C;

3、A happens-before C。

這里的第三個關系是利用傳遞性進行推論的。這里的第三個關系是利用傳遞性進行推論的。

A happens-before B,定義1要求A執(zhí)行結果對B可見,并且A操作的執(zhí)行順序在B操作之前;但與此同時利用HB定義中的第二條,A、B操作彼此不存在數(shù)據(jù)依賴性,兩個操作的執(zhí)行順序對最終結果都不會產(chǎn)生影響。

在不改變最終結果的前提下,允許A,B兩個操作重排序,即happens-before關系并不代表了最終的執(zhí)行順序。




哈嘍,我是小林,就愛圖解計算機基礎,如果覺得文章對你有幫助,歡迎分享給你的朋友,也給小林點個「在看」,這對小林非常重要,謝謝你們,給各位小姐姐小哥哥們抱拳了,我們下次見!


推薦閱讀

你不好奇 Linux 是如何收發(fā)網(wǎng)絡包的?

小小的 float,藏著大大的學問

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

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

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

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

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

關鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產(chǎn)品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日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

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

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

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

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

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

關鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

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

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

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

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