Nein, dann müsste ocpds als Singleton implementiert sein, und das wäre schlecht.TomBola hat gesagt.:naja ich kann doch immer nur eine instanz von ocpds erzeugen.
Streich das Wort "Singleton" und nenn die Methode getDataSource().TomBola hat gesagt.:Hmmm stimmt es ist keine Instanz sondern nur eine variable... Ok es ist also kein Singleton... macht doch aber so wie ich es implementiert habe sinn?!
TomBola hat gesagt.:Hmmm stimmt es ist keine Instanz sondern nur eine variable... Ok es ist also kein Singleton...
dataSource = OracleConnectionPool.setupDataSource();
// Create a pooled connection
pc = dataSource.getPooledConnection();
conn = pc.getConnection();
stmt = conn.createStatement();
public class SingleTon {
private static SingleTon instance;
private SingleTon() {
}
public static SingleTon getInstance() {
if(instance == null) {
synchronized(SingleTon.class) {
if(instance == null) instance = new SingleTon();
}
}
return instance;
}
}
Vorsicht: Das ist Double-Checked-Locking. Bis einschließlich Java 1.4 funktioniert das so nicht. Ab Java 5 klappt es, wenn man da noch ein volatile spendiert.xdavidx hat gesagt.:Durch synchronized auch "Threadsicher"!
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
xdavidx hat gesagt.:SP nutzt man doch nur bei Objekten Oo
- private Konstruktor
- private statische Referenz auf die Klasse
- statische Methode mit Prüfung, die die Referenz der Klasse "belegt" und returnt!
tfa hat gesagt.:Es spricht nichts dagegen, die ganze Methode synchronized zu definieren. Dann hat man keine Probleme.
Eine Methode die zB. getInstance heisst und diese eine Instanz der Klasse zurückgibt allerdings schon, und diese fehlte dir eben.- statische Methode mit Prüfung, die die Referenz der Klasse "belegt" und returnt!
Dieses Locking ist billig. Es sei denn, Du willst die Methode ein paar Millionen mal pro Sekunde aufrufen.byto hat gesagt.:tfa hat gesagt.:Es spricht nichts dagegen, die ganze Methode synchronized zu definieren. Dann hat man keine Probleme.
Finde ich aber auch nicht so schön. Dann wird bei jedem Aufruf gelockt, selbst wenn das Singleton längst instanziert ist.
Mal abgesehen von der Singleton-Problematik finde ich an Lazy-Initialization nichts schlimmes. Natürlich nur, wenn die Objekterzeugung teuer ist. Lieber 1000 mal ein paar Millisekunden warten als einmal ein paar Sekunden.byto hat gesagt.:Am besten ist es imho, die Anwendung auf maximal ein Singleton zu beschränken, das nicht lazy initialisiert wird.
Nur macht es bei einem Singelton keinen Sinn, weil bei direkt Initialisierung die Initialisierung geschiet sobald die Klasse 'angefasst', bei Pseudo-Lazy sobald getInstance aufgerufen wird. Wann verwendet man die Singelton Klasse ohne gleichzeitig getInstance aufzurufen? Wozu soll das also gut sein?tfa hat gesagt.:Mal abgesehen von der Singleton-Problematik finde ich an Lazy-Initialization nichts schlimmes. Natürlich nur, wenn die Objekterzeugung teuer ist. Lieber 1000 mal ein paar Millisekunden warten als einmal ein paar Sekunden.
Was meinst Du mit Pseudo-Lazy? Lazy-Initialisierung bedeutet, dass das Objekt erst dann initialisiert wird, wenn es gebraucht wird und nicht schon bei Programmstart. Das ist durchaus legitim. Bei größeren Systemen kannst du dadurch einen Slow-Start verhindern.Wildcard hat gesagt.:Nur macht es bei einem Singelton keinen Sinn, weil bei direkt Initialisierung die Initialisierung geschiet sobald die Klasse 'angefasst', bei Pseudo-Lazy sobald getInstance aufgerufen wird.
Wenn Du Module hast, die nicht zwangsläufig bei jeder Programmausführung verwendet werden?Wann verwendet man die Singelton Klasse ohne gleichzeitig getInstance aufzurufen? Wozu soll das also gut sein?
schalentier hat gesagt.:1. Du solltest den Logger an allen Stellen nutzen (und kein System.out.println)
2. Wenn das funktioniert ist doch gut, wenn du den Quellcode verbessern willst:
- static entfernen
- 2 Methoden drauss machen:
-- loadProperties()
-- createDataSource()
- Entscheiden fuer: Singleton oder Factory (wahlweise AbstractFactory oder FactoryMethod) und das entsprechend umsetzen
OracleDataSourcePool.getInstance().setupDataSource()
byto hat gesagt.:Was meinst Du mit Pseudo-Lazy? Lazy-Initialisierung bedeutet, dass das Objekt erst dann initialisiert wird, wenn es gebraucht wird und nicht schon bei Programmstart. Das ist durchaus legitim. Bei größeren Systemen kannst du dadurch einen Slow-Start verhindern.Wildcard hat gesagt.:Nur macht es bei einem Singelton keinen Sinn, weil bei direkt Initialisierung die Initialisierung geschiet sobald die Klasse 'angefasst', bei Pseudo-Lazy sobald getInstance aufgerufen wird.
Wenn Du Module hast, die nicht zwangsläufig bei jeder Programmausführung verwendet werden?Wann verwendet man die Singelton Klasse ohne gleichzeitig getInstance aufzurufen? Wozu soll das also gut sein?
private static Singleton instance = new Singleton();
schalentier hat gesagt.:Zur Zeit hast du eine statische Methode in deiner Klasse. Statische Methoden sind oftmals nicht so dolle, denn die Wiederverwendbarkeit selbiger ist eingeschraenkt (kannst z.B. nicht ueberschreiben). Es ist halt nicht richtig objektorientiert.
Deshalb mach das static weg. Dann kannst du die Methode natuerlich nur an einer Instanz der Klasse aufrufen. Wenn du nun sicherstellen willst, dass es in deinem Programm nur genau eine Instanz der Klasse gibt, machst du ein Singleton. In diesem gibt es nur noch genau eine static Methode (getInstance) die dir die eine Instanz zurueckliefert. An dieser kannst du deine setupDataSource() aufrufen.
z.B.:
Code:OracleDataSourcePool.getInstance().setupDataSource()
Jetzt koenntest du noch eine abstrakte Klasse DataSourcePool erstellen, OracleDataSourcePool von dieser ableiten und dort eine Methode loadProperties() hinpacken. Andere DataSourcePool-Implementierungen koennten diese Methode dann wiederverwenden. Das ist OOP.
Ob sich der scheinbare Mehraufwand in deinem konkreten Fall lohnt, musst du aber selbst entscheiden.
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.PooledConnection;
import oracle.jdbc.pool.OracleConnectionPoolDataSource;
import org.apache.log4j.Logger;
public class OracleConnectionPool {
private static final Logger log = Logger.getLogger(OracleConnectionPool.class);
private static OracleConnectionPoolDataSource ocpds = null;
private Properties prop = null;
private static OracleConnectionPool instance = new OracleConnectionPool();
private Connection conn=null;
private OracleConnectionPool() {
}
private void loadProperty() {
// Load properties
prop = new Properties();
try {
prop.load(new FileInputStream("db.properties"));
} catch (FileNotFoundException e) {
log.error("File not found Exception", e);
} catch (IOException e) {
log.error("Property IO Exception", e);
}
}
public static OracleConnectionPool getInstance() {
return instance;
}
public Connection setupDataSource() {
if (ocpds == null) {
instance.loadProperty();
log.info("!null")
// Create a OracleConnectionPoolDataSource instance
try {
ocpds = new OracleConnectionPoolDataSource();
// Set connection parameters
ocpds.setURL(prop.getProperty("connectURL"));
ocpds.setUser(prop.getProperty("user"));
ocpds.setPassword(prop.getProperty("password"));
PooledConnection pc = ocpds.getPooledConnection();
Connection conn = pc.getConnection();
} catch (SQLException e) {
log.error("SQL Error", e);
}
return conn;
} else {
System.out.println("OracleConnectionPoolDataSource is != null");
return conn;
}
}
}
Stimmt, Du hast Recht!Wildcard hat gesagt.:Diese Instanz wird nicht erzeugt, wenn die VM startet, sondern erst sobald Singleton auch verwendet wird. Es ist damit genauso Lazy wie die aufgeblasene, langsamere Pseudo Lazy Initializing Variante. Der einzige Unterschied tritt auf, wenn du Singleton.SOME_CONSTANT verwendest, ohne in absehbarer Zeit das erste mal Singleton.getInstance() aufzurufen.Code:private static Singleton instance = new Singleton();
Sind wir mal ehrlich, das hat keine Praxisrelevanz
Saxony hat gesagt.: