2013-03-29 166 views

回答

2

運行javap命令oracle.sql.ArrayDescriptor類。可以觀察到oracle.sql.ArrayDescriptor類的公共方法都沒有同步。這裏是什麼javap告訴:

E:\users>javap oracle.sql.ArrayDescriptor 
Compiled from "ArrayDescriptor.java" 
public class oracle.sql.ArrayDescriptor extends oracle.sql.TypeDescriptor implem 
ents java.io.Serializable{ 
    public static final int TYPE_VARRAY; 
    public static final int TYPE_NESTED_TABLE; 
    public static final int CACHE_NONE; 
    public static final int CACHE_ALL; 
    public static final int CACHE_LAST; 
    static final long serialVersionUID; 
    public static final boolean TRACE; 
    public static final boolean PRIVATE_TRACE; 
    public static final java.lang.String BUILD_DATE; 
    public static oracle.sql.ArrayDescriptor createDescriptor(java.lang.String, java.sql.Connection) throws java.sql.SQLException; 
    public static oracle.sql.ArrayDescriptor createDescriptor(java.lang.String, java.sql.Connection, boolean, boolean) throws java.sql.SQLException; 
    public static oracle.sql.ArrayDescriptor createDescriptor(oracle.sql.SQLName, java.sql.Connection) throws java.sql.SQLException; 
    public static oracle.sql.ArrayDescriptor createDescriptor(oracle.sql.SQLName, java.sql.Connection, boolean, boolean) throws java.sql.SQLException; 
    public static oracle.sql.ArrayDescriptor createDescriptor(oracle.jdbc.oracore.OracleTypeCOLLECTION) throws java.sql.SQLException; 
    public oracle.sql.ArrayDescriptor(java.lang.String, java.sql.Connection) throws java.sql.SQLException; 
    public oracle.sql.ArrayDescriptor(oracle.sql.SQLName, java.sql.Connection) throws java.sql.SQLException; 
    public oracle.sql.ArrayDescriptor(oracle.sql.SQLName, oracle.jdbc.oracore.OracleTypeCOLLECTION, java.sql.Connection) throws java.sql.SQLException; 
    public oracle.sql.ArrayDescriptor(oracle.jdbc.oracore.OracleTypeCOLLECTION, java.sql.Connection) throws java.sql.SQLException; 
    static oracle.sql.ArrayDescriptor createDescriptor(oracle.sql.SQLName, byte[], int, byte[], byte[], oracle.jdbc.internal.OracleConnection, byte[]) throws java.sql.SQLException; 
    public int getBaseType() throws java.sql.SQLException; 
    public java.lang.String getBaseName() throws java.sql.SQLException; 
    public oracle.jdbc.oracore.OracleTypeCOLLECTION getOracleTypeCOLLECTION(); 
    public int getArrayType() throws java.sql.SQLException; 
    public long getMaxLength() throws java.sql.SQLException; 
    public java.lang.String descType() throws java.sql.SQLException; 
    java.lang.String descType(java.lang.StringBuffer, int) throws java.sql.SQLException; 
    int toLength(oracle.sql.ARRAY) throws java.sql.SQLException; 
    byte[] toBytes(oracle.sql.ARRAY, boolean) throws java.sql.SQLException; 
    oracle.sql.Datum[] toOracleArray(oracle.sql.ARRAY, long, int, boolean) throws java.sql.SQLException; 
    java.lang.Object[] toJavaArray(oracle.sql.ARRAY, long, int, java.util.Map, boolean) throws java.sql.SQLException; 
    public java.sql.ResultSet toResultSet(oracle.sql.ARRAY, long, int, java.util.Map, boolean) throws java.sql.SQLException; 
    public java.sql.ResultSet toResultSet(oracle.sql.Datum[], long, int, java.util.Map) throws java.sql.SQLException; 
    public java.sql.ResultSet toResultSetFromLocator(byte[], long, int, java.util.Map) throws java.sql.SQLException; 
    public java.sql.ResultSet toResultSetFromImage(oracle.sql.ARRAY, long, int, java.util.Map) throws java.sql.SQLException; 
    public static java.lang.Object[] makeJavaArray(int, int) throws java.sql.SQLException; 
    oracle.sql.Datum[] toOracleArray(java.lang.Object, long, int) throws java.sql.SQLException; 
    java.lang.Object toNumericArray(oracle.sql.ARRAY, long, int, int, boolean) throws java.sql.SQLException; 
    public int getTypeCode() throws java.sql.SQLException; 
    public byte[] toBytes(oracle.sql.Datum[]) throws java.sql.SQLException; 
    public byte[] toBytes(java.lang.Object[]) throws java.sql.SQLException; 
    public int length(byte[]) throws java.sql.SQLException; 
    public oracle.sql.Datum[] toArray(byte[]) throws java.sql.SQLException; 
    public oracle.sql.Datum[] toArray(java.lang.Object) throws java.sql.SQLException; 
    public java.sql.ResultSet toResultSet(byte[], java.util.Map) throws java.sql.SQLException; 
    public java.sql.ResultSet toResultSet(byte[], long, int, java.util.Map) throws java.sql.SQLException; 
    public static int getCacheStyle(oracle.sql.ARRAY) throws java.sql.SQLException; 
    static {}; 
} 

因此,你應該繼續與這個類假設它不是線程安全的。

UPDATE
按照您的要求,因爲類的所有私人和公共變量是最後所以沒有辦法的情況下的內部狀態會被其方法得到改變。

E:\users>javap -private oracle.sql.TypeDescriptor 
Compiled from "TypeDescriptor.java" 
public abstract class oracle.sql.TypeDescriptor extends java.lang.Object implements java.io.Serializable{ 
    public static boolean DEBUG_SERIALIZATION; 
    static final long serialVersionUID; 
    oracle.sql.SQLName sqlName; 
    oracle.jdbc.oracore.OracleNamedType pickler; 
    transient oracle.jdbc.internal.OracleConnection connection; 
    private static final java.lang.String _Copyright_2004_Oracle_All_Rights_Reserved_; 
    public static final boolean TRACE; 
    public static final boolean PRIVATE_TRACE; 
    public static final java.lang.String BUILD_DATE; 
    protected oracle.sql.TypeDescriptor(); 
    protected oracle.sql.TypeDescriptor(java.lang.String, java.sql.Connection)throws java.sql.SQLException; 
    protected oracle.sql.TypeDescriptor(oracle.sql.SQLName, java.sql.Connection)throws java.sql.SQLException; 
    protected oracle.sql.TypeDescriptor(oracle.sql.SQLName, oracle.jdbc.oracore.OracleTypeADT, java.sql.Connection)throws java.sql.SQLException; 
    protected oracle.sql.TypeDescriptor(oracle.jdbc.oracore.OracleTypeADT, java.sql.Connection)throws java.sql.SQLException; 
    public synchronized java.lang.String getName() throws java.sql.SQLException; 
    public synchronized oracle.sql.SQLName getSQLName() throws java.sql.SQLException; 
    void initSQLName()  throws java.sql.SQLException; 
    public java.lang.String getSchemaName()  throws java.sql.SQLException; 
    public java.lang.String getTypeName()  throws java.sql.SQLException; 
    public oracle.jdbc.oracore.OracleNamedType getPickler(); 
    public oracle.jdbc.internal.OracleConnection getInternalConnection(); 
    public void setPhysicalConnectionOf(java.sql.Connection); 
    public abstract int getTypeCode()  throws java.sql.SQLException; 
    public static oracle.sql.TypeDescriptor getTypeDescriptor(java.lang.String,oracle.jdbc.OracleConnection) throws java.sql.SQLException; 
    public static oracle.sql.TypeDescriptor getTypeDescriptor(java.lang.String,oracle.jdbc.OracleConnection, byte[], long) throws java.sql.SQLException; 
    public boolean isInHierarchyOf(java.lang.String) throws java.sql.SQLException; 
    private void writeObject(java.io.ObjectOutputStream)throws java.io.IOException; 
    private void readObject(java.io.ObjectInputStream)throws java.io.IOException, java.lang.ClassNotFoundException; 
    public void setConnection(java.sql.Connection) throws java.sql.SQLException; 
    public static java.lang.String getSubtypeName(oracle.jdbc.OracleConnection,byte[], long) throws java.sql.SQLException; 
    public void initMetadataRecursively()  throws java.sql.SQLException; 
    public void initNamesRecursively()  throws java.sql.SQLException; 
    public void fixupConnection(oracle.jdbc.internal.OracleConnection) throws java.sql.SQLException; 
    public java.lang.String toXMLString()  throws java.sql.SQLException; 
    public void printXML(java.io.PrintStream)  throws java.sql.SQLException; 
    void printXML(java.io.PrintWriter, int)  throws java.sql.SQLException; 
    void printXMLHeader(java.io.PrintWriter)  throws java.sql.SQLException; 
    static {}; 
} 

因此有這些非最終變量將通過各種線程訪問oracle.sql.ArrayDescriptor類的同一對象不可預測地改變的可能性:如下所示,但oracle.sql.ArrayDescriptor也繼承oracle.sql.TypeDescriptor含有非最終變量。所以我仍然認爲它不是Thread-safe

+0

感謝您的帖子。但是,爲了使該類的實例保持線程安全,類的方法不需要同步。例如,如果方法不影響類實例的內部狀態,則不需要同步它們。這裏沒有任何方法似乎在修改實例變量的狀態,所以很可能該類是線程安全的。 –

+0

我同意你的第一點..你怎麼能確定這些方法不會修改實例變量的內部狀態? –

+0

@ user2200690:當然,ArrayDescriptor的所有實例變量都是最終的,包括私有的一個。但是它的超類('oracle.sql.TypeDescriptor')實例變量不是最終的。所以這些變量狀態可能會變得不可預測地發生變化。 –

1

猜猜是什麼?源代碼似乎並不在人們可以找到的正常位置上提供,因此除了要求Oracle支持之外,無法確定。

基於API設計,它可能是線程安全的。沒有setter,看起來類從客戶角度看是不可改變的。您可以通過在字節碼文件中指向javap並查看實例變量是否都被聲明爲final來確認此情況。

但是,如果您無法獲得確認,安全的方法是假定該類不是線程安全的。

+0

根據下面的帖子,似乎所有的實例變量都被聲明爲final。我將嘗試從Oracle支持獲得這個問題的答案。 –