i++和++i的區別,及其執行緒安全問題
i++和++i都是i=i+1的意思,但是過程有些許區別:
i++:先賦值再自加。(例如:i=1;a=1+i++;結果為a=1+1=2,語句執行完後i再進行自加為2)
++i:先自加再賦值。(例如:i=1;a=1+++i;結果為a=1+(1+1)=3,i先自加為2再進行運算)
但是在單獨使用時沒有區別:如for(int i=0;i<10;i++){ }和for(int i=0;i<10;++i) { }沒有區別。
i++和++i的執行緒安全分為兩種情況:
1、如果i是區域性變數(在方法裡定義的),那麼是執行緒安全的。因為區域性變數是執行緒私有的,別的執行緒訪問不到,其實也可以說沒有執行緒安不安全之說,因為別的執行緒對他造不成影響。
2、如果i是全域性變數(類的成員變數),那麼是執行緒不安全的。因為如果是全域性變數的話,同一程序中的不同執行緒都有可能訪問到。
如果有大量執行緒同時執行i++操作,i變數的副本拷貝到每個執行緒的執行緒棧,當同時有兩個執行緒棧以上的執行緒讀取執行緒變數,假如此時是1的話,那麼同時執行i++操作,再寫入到全域性變數,最後兩個執行緒執行完,i會等於3而不會是2,所以,出現不安全性。
相關推薦
i++和++i的區別,及其執行緒安全問題
i++和++i都是i=i+1的意思,但是過程有些許區別:i++:先賦值再自加。(例如:i=1;a=1+i++;結果為a=1+1=2,語句執行完後i再進行自加為2)++i:先自加再賦值。(例如:i=1;a=1+++i;結果為a=1+(1+1)=3,i先自加為2再進行運算)但是在
i++和++i的區別,及其線程安全問題
變量 等於 線程變量 ++i 自加 單獨 時有 線程棧 單獨使用 i++和++i都是i=i+1的意思,但是過程有些許區別: i++:先賦值再自加。(例如:i=1;a=1+i++;結果為a=1+1=2,語句執行完後i再進行自加為2) ++i:先自加再賦值。(例如:i=1;
5個步驟,教你瞬間明白執行緒和中原六仔出售執行緒安全
記得中原六仔出售 dsluntan.com Q:3393756370 VX:17061863513今年3月份剛來杭州面試的時候,有一家公司的技術總監問了我這樣一個問題:你來說說有哪些執行緒安全的類?我心裡一想,這我早都背好了,稀里嘩啦說了一大堆。 他又接著問:
Java併發程式設計基礎//程序:每個程序都有獨立的程式碼和資料空間(程序上下文),程序間的切換開銷比較大,一個程序包含1-n個執行緒 //執行緒:同一類執行緒共享程式碼和資料空間,每個執行緒擁有獨立的執行棧和程式計
1.實現多執行緒的兩種方式: (1)繼承Thread類; (2)實現Runnable介面 //程序:每個程序都有獨立的程式碼和資料空間(程序上下文),程序間的切換開銷比較大,一個程序包含1-n個執行緒 //執行緒:同一類執行緒共享程式碼和資料空間,每個執行緒擁有獨立的執行
Spring bean 和單例bean的執行緒安全
Bean的作用域 Spring 3中為Bean定義了5中作用域,分別為singleton(單例)、prototype(原型)、request、session和global session,5種作用域說明如下: singleton:單例模式,Spring I
寫一下單例模式,考慮執行緒安全與執行緒不安全的情況
凡是提到設計模式,面試官很喜歡問最簡單的單例模式。 方法一 單例模式最簡單的寫法如下 public class SingletonPatternA { private static SingletonPatternA instance =
消費RabbitMQ時的注意事項,如何禁止大量的訊息湧到Consumer,保證執行緒安全
按照官網提供的訂閱型寫法( Retrieving Messages By Subscription ("push API")) 我發現,RabbitMQ伺服器會在短時間內傳送大量的訊息給Consumer,然後,如果你沒有來得及Ack的話,那麼服務端會積壓大量的UnAcked訊息,而Cons
單例設計模式(餓漢式,懶漢式(1,有執行緒安全問題,2,安全高效))
package cn.itcast.mobilesafexian2.test; public class Student { /* (1)單例模式(只需建立一個物件) (外界訪問直接Student.getStudent 即可獲得物件 ) (餓漢式:在載入的時候建立物件{
C++11:基於std::queue和std::mutex構建一個執行緒安全的佇列
C++中的模板std::queue提供了一個佇列容器,但這個容器並不是執行緒安全的,如果在多執行緒環境下使用佇列,它是不能直接拿來用的。 基於它做一個執行緒安全的佇列也並不複雜。基本的原理就是用std::mutext訊號量對std::queue進行訪問控制,以
面試題,Servlet 執行緒安全嗎?
Servlet的工作原理:首先客戶傳送一個請求,Servlet是呼叫service()方法對請求進行響應的,通過原始碼可見,service()方法中對請求的方式進行了匹配,選擇呼叫doGet,doPost等這些方法,然後再進入對應的方法中呼叫邏輯層的方法,實現對客戶的響應。在
JavaScript運算符:遞增和遞減(++i,--i 和 i++,i-- 的區別)
nbsp key mic comment 包含 -- 效應 1+n com 遞增和遞減操作符直接借鑒自C,而且各有兩個版本:前置型 (遞增 ++i ,遞減 --i )和 後置型 (遞增 i++ ,遞減 i-- )。書本上對兩者的定義是:前置型應該位於要操作的變量之前,而後置
關於hashmap和hashtable的區別,及如何使hashmap變得執行緒安全?(除了synchronized)---concurrentHashmap
我們都知道hashmap是執行緒不安全的,而效率也比較高,他允許我們存入null鍵及null值; 而 hashtable 是執行緒安全的,其效率比較低,不允許我們存入null鍵和null值; 除了非同步及允許使用null值,hashmap與hashtable基本相同; 那麼為什麼hash
抽象類和介面的區別,內部類引用外部方法final引數,守護執行緒和使用者執行緒
abstract class和interface有什麼區別? 答:宣告方法的存在而不去實現它的類被叫做抽象類(abstract class),它用於要建立一個體現某些基本行為的類,併為該類宣告方法,但不能在該類中實現該類的情況。不能建立abstract 類的
C語言自增自減,i++和++i的區別
自增、自減運算子。 自增:i++,++i 自減:i--,--i i++和++i的區別:當i++和++i單獨一行時,兩者的作用相同,都實現i=i+1;但不同之處在於i++先使用i的之後,再執行i=i+1,而++i是先執行i=i+1,在執行使用i的值。 而 a = ++i,相當於 i=i+1; a = i;而
JAVA for迴圈執行順序 及 i++和++i的區別
1.i與i++的區別是: ++i 是先執行 i=i+1 再使用 i 的值,而 i++ 是先使用 i 的值再執行 i=i+1。 2.但是如果不瞭解 for 迴圈的執行順序則容易出錯。 for迴圈的執行順序如下: for(sta1;sta2;sta3) { st
面試官:都說阻塞 I/O 模型將會使執行緒休眠,為什麼 Java 執行緒狀態卻是 RUNNABLE?
摘要: 原創出處 https://studyidea.cn 「公眾號:程式通事 」歡迎關注和轉載,保留摘要,謝謝! 使用 Java 阻塞 I/O 模型讀取資料,將會導致執行緒阻塞,執行緒將會進入休眠,從而讓出 CPU 的執行權,直到資料讀取完成。這個期間如果使用 jstack 檢視執行緒狀態,卻可以發
js ++i和i++的區別
bsp ons http pre sans 前綴 -h 單位 alt ++i和i++的定義: 1. 如果用前綴運算符對一個變量增1(減1),則在將該變量增1(減1)後,用新值在表達式中進行其他的運算。 2. 如果用後綴運算符對一個變量增1(減1),則用該變量的
i++和++i 的區別
++i ++ 輸出結果 print body nbsp pos 之前 ont 1. i++為後自增 整體表達式的值為自增之前的值 2. ++i為前自增 整體表達式的值為自增後的值 # include <stdio.h> int main(void)
自增自減 i++ 和 ++i的區別
post 宋體 font clas style span 與運算 rom ++ ◆在不參與運算的情況下,i++和++i都是在變量的基礎加1 ◆在參與運算的情況下 Var i=123; Var j=i++; 先將i的值123賦值給j,之後再自增 j的值為123 i
++i和i++的區別
比較 word comm nbsp 引用 x11 AR 常見 循環 ++i和i++區別在於運算順序和結合方向。 js中有兩種自加運算,其運算符均為++,功能為將運算符自加1. 其中: ++VAR被稱為前自加,其後面的變量執行自加操作,其運算為,先執行自加操作,再引用VA