直到最近的IE老出問題,公司派的本本裝的是win2000,用久了里面的IE經常會彈出一個crash的對話框(似乎在XP里就很少見),然后所有打開的IE窗口都只能關閉,解決無方,于是想到了Firefox,試用一下,第一感覺是非??欤还苁莑oad firefox還是打開新的網頁,基本上都是文字刷一下就出來,圖片則延遲了點,不過還是比IE做得好:) 很多小的細節都考慮得比較符合用戶的操作習慣,比如工具欄有一個下載的管理器,管理最近下載的咚咚,不用第三方軟件,而且Firefox比IE小巧多了(4.8M),Simple is beautiful,呵呵,I like it.
2006年7月17日
直到最近的IE老出問題,公司派的本本裝的是win2000,用久了里面的IE經常會彈出一個crash的對話框(似乎在XP里就很少見),然后所有打開的IE窗口都只能關閉,解決無方,于是想到了Firefox,試用一下,第一感覺是非??欤还苁莑oad firefox還是打開新的網頁,基本上都是文字刷一下就出來,圖片則延遲了點,不過還是比IE做得好:) 很多小的細節都考慮得比較符合用戶的操作習慣,比如工具欄有一個下載的管理器,管理最近下載的咚咚,不用第三方軟件,而且Firefox比IE小巧多了(4.8M),Simple is beautiful,呵呵,I like it.
If Java uses the pass-by reference, why won't a swap function work?
Your question demonstrates a common error made by Java language newcomers. Indeed, even seasoned veterans find it difficult to keep the terms straight.
Java does manipulate objects by reference, and all object variables are references. However, Java doesn't pass method arguments by reference; it passes them by value.
Take the badSwap()
method for example:
public void badSwap(int var1, int var2)
{
??int temp = var1;
??var1 = var2;
??var2 = temp;
}
When badSwap()
returns, the variables passed as arguments will still hold their original values. The method will also fail if we change the arguments type from int
to Object
, since Java passes object references by value as well.
Now, here is where it gets tricky:
public void tricky(Point arg1, Point arg2)
{
??arg1.x = 100;
??arg1.y = 100;
??Point temp = arg1;
??arg1 = arg2;
??arg2 = temp;
}
public static void main(String [] args)
{
??Point pnt1 = new Point(0,0);
??Point pnt2 = new Point(0,0);
??System.out.println("X: " + pnt1.x + " Y: " +pnt1.y);
??System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
??System.out.println(" ");
??tricky(pnt1,pnt2);
??System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);
??System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);??
}
If we execute this main()
method, we see the following output:
X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0
The method successfully alters the value of pnt1
, even though it is passed by value; however, a swap of pnt1
and pnt2
fails! This is the major source of confusion. In the main()
method, pnt1
and pnt2
are nothing more than object references. When you pass pnt1
and pnt2
to the tricky()
method, Java passes the references by value just like any other parameter. This means the references passed to the method are actually copies of the original references. Figure 1 below shows two references pointing to the same object after Java passes an object to a method.
Figure 1. After being passed to a method, an object will have at least two references
|
Java copies and passes the reference by value, not the object. Thus, method manipulation will alter the objects, since the references point to the original objects. But since the references are copies, swaps will fail. As Figure 2 illustrates, the method references swap, but not the original references. Unfortunately, after a method call, you are left with only the unswapped original references. For a swap to succeed outside of the method call, we need to swap the original references, not the copies.
Figure 2. Only the method references are swapped, not the original ones
|
O'Reilly's Java in a Nutshell by David Flanagan (see Resources) puts it best: "Java manipulates objects 'by reference,' but it passes object references to methods 'by value.'" As a result, you cannot write a standard swap method to swap objects.
Resources
-
Practical Java Programming Language Guide Peter Haggar (Addison-Wesley 2000):
http://www1.fatbrain.com/asp/bookinfo/bookinfo.asp?theisbn=0201616467 -
Java in a Nutshell David Flanagan (O'Reilly and Associates 1999):
http://www1.fatbrain.com/asp/bookinfo/bookinfo.asp?theisbn=1565924878
一個事務可以定義為由一組操作組成的不可分割的單元,它們要么全部被執行,要么全部不執行以保持事數據完整性。比如,從你的支票帳戶到你的儲蓄賬戶進行100美元的轉帳包含以下兩步操作:從支票賬戶登記借出100美元,然后在儲蓄賬戶添加100美元。這兩步必須同時被執行或者不執行以保護數據的完整性和一致性,以及銀行和客戶之間的利息核算。因此,這兩步的操作組成了一個事務。
事務的屬性
所有的事務都具備以下幾個屬性:原子性、一致性、獨立性以及持久性(縮寫為ACID)。
原子性:意味著不可分割,一組操作是不可分割的,我們稱之為原子的。
一致性:一個事務的轉換必須是把持久化的數據從一個一致的狀態轉換到另一個一致的狀態,任何發生在其間的轉換失敗,都必須保證數據能夠返回轉換之前的那個狀態。
獨立性:? 事務之間應互不影響,也就是說,一個處于未完成狀態的事務(未commit或rollback),必須獨立于其他的事務;即使幾個事務同時運行,對其中每一個事務來講,其他的事務也必須在它之前或者之后完成,所有的并發事務都必須按照實際的順序依次完成。
持久性:一旦一個事務成功地提交完成之后(commit),由該事務所帶來的狀態的改變必須是穩定和持久的,即使在提交完成之后發生了其他的錯誤也不受影響。
因此,一個事務運行的最終結果只有兩個:commit ——每一步操作的成功執行;rollback——由于執行過程中出現了錯誤,rollback保證沒有一步操作執行。
事務獨立性的等級
事務的獨立性用來衡量并發事務中一個事務查看另外一個事務已經update但尚未commit的數據的能力,如果某些事務允許其他事務讀取它已經upadte但尚未commit的數據,這些事務可能會以存在不一致的數據而roll back,或者結束不必要的等待而commit成功。( those transactions could end up with inconsistent data were the transaction to roll back, or end up waiting unnecessarily were the transaction to commit successfully. )
越高等級的獨立性意味著越少的并發性,并且越有可能成為系統性能的瓶頸,但它也減少了讀取到不一致數據的機會。一個好的應用原則是在可接受的系統性能基礎上選擇盡可能高的獨立性。以下是通常的獨立性等級劃分,從最低到最高如下:
ReadUncommitted:已經update但尚未commit的數據可以被其他事務讀取
ReadCommitted:一個事務只有commit了的數據才可被其他事務讀取
RepeatableRead: 一個事務只有commit了的數據才可被其他事務讀取,重復的讀取則會導致和數據尚未提交狀態時一樣的結果
Serializable: 這是最高等級的獨立性等級,保證了一個事務對數據排他性的讀寫訪問,它包含了ReadCommitted和RepeatableRead級別的所有限制,同時保證所有的事務必須逐個執行,以獲取最大程度的數據完整性,這導致了最低的運行性能以及最少的并發性,注意,這里的Serializable和Java里面的java.io.Serializable毫無聯系。
J2EE支持的事務
J2EE平臺包括了規范、兼容性test suite,application開發藍圖,以及參考實現?;谙嗤囊幏?,眾多的開發商提供了不同的應用服務器和實現。J2EE組件的設計是基于規范而非基于特定的產品(比如基于某個特定的應用服務器)。J2EE應用程序里的組件利用了J2EE容器和服務器所提供的基礎服務,因此只需要將關注點放在處理業務邏輯上,J2EE通過部署描述符,使用聲明式的屬性,支持可伸縮的部署以及在目標環境中可定制的能力。J2EE的目標是保護IT投資以及降低application開發的成本,J2EE的組件可以自己開發也可從外面的代理商處獲得,這樣可以使得你的IT部門的成本降低并提高了可伸縮性。
J2EE所提供的基礎服務中一個重要部分便是對事務的支持,在J2EE規范中,描述了Java事務的API(JTA,Java Transaction API),JTA主要包括了幾個接口:javax.transaction.UserTransaction和javax.transaction.TransactionManager。UserTransaction接口提供給application組件,對application組件而言,底下的J2EE服務器和TransactionManager之間的交互是透明的。TransactionManager的實現提供給應用服務器對事務邊界的控制。J2EE的application組件提供了對JTA的UserTransaction和JDBC的事務的支持。
J2EE平臺支持了兩種類型的事務管理范式:聲明式的事務和編程式的事務(declarative transaction demarcation and programmatic transaction demarcation. )
...(to be continued)