如果同時發生的兩個事件更改變量的值,會發生什麼情況?在Actionscript 3中,如果不同的事件同時改變一個變量的值會發生什麼?
例如,我們有兩個對象:A
和B
,加載到stage
和階段變量名爲varx
。
下面的代碼被嵌入在A
的第五幀:
stage.varx = 9
在另一方面,我們有,在B
的第五幀,以下代碼:
stage.varx = 2
所以當兩個動畫片段都達到第五幀時,varx
的值是什麼?
如果同時發生的兩個事件更改變量的值,會發生什麼情況?在Actionscript 3中,如果不同的事件同時改變一個變量的值會發生什麼?
例如,我們有兩個對象:A
和B
,加載到stage
和階段變量名爲varx
。
下面的代碼被嵌入在A
的第五幀:
stage.varx = 9
在另一方面,我們有,在B
的第五幀,以下代碼:
stage.varx = 2
所以當兩個動畫片段都達到第五幀時,varx
的值是什麼?
TL; DR
A
和B
不會在進入第五框架同樣的確切時間,除非你做的事情非常不尋常。 A
或B
會先到達,最後一個將覆蓋第一個值。只要確保你沒有按照一定的順序發射depend
。即使你做了一些不尋常的事情,它仍然是一個非問題。
這是回答,假設您指的是舞臺中帶有多個對象的單個程序。如果你正在談論多個試圖共享某種全局stage
狀態的程序(我不確定它們是否會共享相同的stage
對象),那麼我不能肯定地說,但它很可能會以同樣的方式工作。
Flash 一般不使用多線程。事實上,直到兩年前,AS3才完全支撐它,給予或承擔。 99%的時間,swfs根本不會使用它。
在這種情況下,A
和B
不會同時輸入它們的第五幀。不可能。一個必須先進入第五個框架,然後是另一個。它需要多線程才能在單個程序中改變這一事實。
所以我們假設你有事件處理程序,它們在每個進入第五幀時觸發。這是會發生什麼事情:
stage
變量爲您爲該特定處理程序提供的任何值。有關AS3事件的一件事情是,它們不像您初次啓動時期望的那樣與語言的核心核心密切相關。它們只是「常用API」中的一個類,它已經完全圍繞它們構建了API的一部分。所以,當你處理一個事件時,真正發生的一切就是一些代碼突然決定要發送一個事件。然後它創建一個類Event
的實例,然後調用它的一個函數dispatchEvent
,傳入Event
作爲參數。然後dispatchEvent
只是查看回調函數列表,並開始一個接一個地調用它們,將Event
作爲參數傳遞給它們中的每一個。其中一個回調是你的事件處理程序。一個回調稱爲並返回,然後是下一個,然後是下一個。所以事件處理是整體異步的,事件的調度和處理是以基本同步的方式進行的。
一件事情規則的例外是在更現代版本的Flash中使用工作線程時。這實際上可能比多線程(可以說是兩者的混合)稍微接近多處理,因爲它實際上需要使用通過主要swf通過「工作人員」進行通信的輔助嵌入式swfs。所以是的,你可能會碰到這種情況,他們都試圖在同一時間混淆同一個變量。
這是計算機科學中一個非常普遍的問題,但最簡單的答案是這樣的:無論您是Flash還是.NET,或者其他什麼,您都可以在其上編程的平臺通常旨在阻止您無法從兩個不同的來源以相同的確切時間寫入完全相同的變量和/或存儲器地址。除非您決定降低級別,否則您通常可以認爲該平臺將擁有自己的內部鎖定機制,可以防止同時寫入。這幾乎肯定適用於此。
然而有兩個警告此:
這適用於一個特定的變量/存儲地址。它不一定適用於,比方說,整個字符串的內部狀態。使用像C++這樣的語言的多線程的教科書問題是,如果兩個線程試圖在相同的確切時間連接相同的完全字符串變量。在C++中,字符串實際上是一個數組chars
(或者一個實例std::string
,它將對此進行封裝),只有當它到達具有整數值0
的元素時纔會結束。因此,兩個試圖爲字符串添加字符的線程可能會在稍微不同的時間開始,這兩個線程在第一個完成之前開始,此時第二個線程將更改字符x
的值,而第一個字符將更改字符的值x + y
。儘管如此,在高級語言中,通常會爲字符串特別設置內置的保護措施,但是當給定對象中的多個變量發生更改時,您仍然可以輕鬆地運行該操作。
比賽條件。 Vesper觸及了這一點。雖然A
和B
可能不會完全同時更改stage.x
,但您仍然不清楚它們將如何更改它的順序。而且它不會構建到平臺中,無論是Flash還是大部分任何內容其他。當你有異步的東西時,即使它只是在表面和單線程環境中,你也必須在那裏放置邏輯,以確保其他東西不依賴於它以任何特定順序執行。
這通常適用於計算機科學。您可能已經知道了大部分這一點,但本質上,答案是stage.x
沒有什麼不尋常的事情發生;只是你無法分辨哪個價值會首先或最後。
當A
到達第五幀stage.varx
成爲9
stage.varx = 9
當B
到達第五幀stage.varx
成爲2
stage.varx = 2
讓我們假設A
是第一個和B
ccomes第二,則該值將是2,就像如果我們指定
var i:int = 2; var i:int = 3; //output i = 3
這麼簡單
它全部在一個線程中運行(所以在同一時間沒有任何事情發生),因此最後執行的任何幀都將佔上風。在顯示列表上可能有A或B的哪個更高(例如圖層順序)。你爲什麼不測試它並找出答案?如果你這樣做,測試一堆,看看它是否一致。 – BadFeelingAboutThis
如果您的A和B具有不同的幀速率,或者正在進行更改,您可能會遇到一組稱爲「競爭條件」的事件。我會說你不應該讓這種情況發生,因爲在開始使用單個變量的這種雙重無狀態設置時,很難在代碼中發現錯誤。 – Vesper