我正在使用由于某种原因无效的单身人士,无法弄清楚原因
private static ConnectionUtility instance;
public static ConnectionUtility getInstance() {
if(instance == null){
instance = new ConnectionUtility();
}
return instance;
}
在上面显示的代码中,第二次执行此代码时,实例不为null,已经创建了一个实例,所以在第二次执行此代码时,它应该直接转到返回实例行并跳过instance = new ConnectionUtility()行。但是在第二次迭代时,它将尝试在已存在的情况下创建另一个ConnectionUtility对象的实例。它为什么这样做?如何解决这个问题?
下面发布的完整代码:适用于3类ConnectionUtility和MultiThreader以及开始
public class Start {
public static void main(String args[]) {
ConnectionUtility.getInstance();
} // end main
} // end Start
public class ConnectionUtility extends javax.swing.JFrame
implements MultiThreader.OnSendResultListener {
private static ConnectionUtility instance;
public static ConnectionUtility getInstance() {
if(instance == null){
instance = new ConnectionUtility();
}
return instance;
}
private ConnectionUtility() {
initComponents();
this.setVisible(true);
serverRunner();
File fileOne = new File("C:/DBFiles");
if(!fileOne.exists()){
fileOne.mkdir();
}
File fileTwo = new File("C:/DBFilesOut");
if(!fileTwo.exists()){
fileTwo.mkdir();
}
}
public void serverRunner(){
runner = true;
try {
serversocket = new ServerSocket(6789, 100);
System.out.println();
} catch (IOException ex) {
Logger.getLogger(ConnectionUtility.class.getName()).log(Level.SEVERE, null, ex);
}
while(runner){
try {
socket = serversocket.accept();
addAndDisplayTextToString("new connection, inet socket address >>> " + socket.getPort());
System.out.println(displayString);
} catch (IOException ex) {
Logger.getLogger(ConnectionUtility.class.getName()).log(Level.SEVERE, null, ex);
}
// MultiThreader multi = new MultiThreader(socket, this);
MultiThreader multi = new MultiThreader(socket);
Thread t = new Thread(multi);
t.start();
} // end while runner loop
} // end serverRunner method
public static void addAndDisplayTextToString(String setString){
StringBuilder stb = new StringBuilder(displayString);
setString = setString + "\n";
if(stb.toString() == ""){
stb.append(setString);
}else if(stb.toString() != ""){
stb.insert(0, setString);
}
int counter = 0;
for(int i = 0; i < stb.length(); i++){
if(stb.substring(i, i + 1).equals("\n")){
counter++;
}
}
// get the last index of "\n"
int lastIndex = stb.lastIndexOf("\n");
int maximum = 4;
if(counter >= maximum){
stb.delete(lastIndex, stb.length());
System.out.println();
}
displayString = stb.toString();
}
@Override
public void onStringResult(String transferString) {
addAndDisplayTextToString(transferString);
jTextArea1.setText(displayString);
System.out.println("RETURNED TRING " + transferString);
}
} // class ConnectionUtility
public class MultiThreader implements Runnable {
public MultiThreader(Socket s) {
socket = s;
stpe = new ScheduledThreadPoolExecutor(5);
listener = ConnectionUtility.getInstance();
}
@Override
public void run() {
long serialNumber = 0;
int bufferSize = 0;
// get input streams
try {
bis = new BufferedInputStream(socket.getInputStream());
dis = new DataInputStream(bis);
} catch (IOException ex) {
Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
}
sendStatus("New connection strarted");
// read in streams from server
try {
fileSizeFromClient = dis.readInt();
sendStatus("File size from client " + fileSizeFromClient);
serialNumber = dis.readLong();
sendStatus("Serial mumber from client " + serialNumber);
} catch (IOException ex) {
Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
}
try {
bufferSize = socket.getReceiveBufferSize();
sendStatus("Buffer size " + bufferSize);
} catch (SocketException ex) {
Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
}
String serialString = String.valueOf(serialNumber);
File fileDirectory = new File("C:" + File.separator + "DOWNLOAD" + File.separator + serialNumber + File.separator);
fileDirectory.mkdir();
File file = new File("C:" + File.separator + "DOWNLOAD" + File.separator + serialNumber + File.separator + "JISSend.pdf");
try {
file.createNewFile();
} catch (IOException ex) {
Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
}
try {
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
dos = new DataOutputStream(bos);
} catch (FileNotFoundException ex) {
Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
}
int count = 0;
byte[] buffer = new byte[fileSizeFromClient];
try {
int totalBytesRead = 0;
while(totalBytesRead < fileSizeFromClient){
int bytesRemaining = fileSizeFromClient - totalBytesRead;
int bytesRead = dis.read(buffer, 0, (int)Math.min(buffer.length, bytesRemaining));
if(bytesRead == -1){
break;
}else{
dos.write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
}
}
} catch (IOException ex) {
Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
}
try {
dos = new DataOutputStream(socket.getOutputStream());
} catch (IOException ex) {
Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
}
stpe.schedule(new CompareFiles(), 0, TimeUnit.SECONDS);
stpe.schedule(new CloseResources(), 2, TimeUnit.SECONDS);
} // end run method
public class CompareFiles implements Runnable {
@Override
public void run() {
int returnInt = 0;
FileInputStream fis = null;
File file = new File("C:/DOWNLOAD/JISSend.pdf");
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException ex) {
Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
}
int fileLength = (int) file.length();
sendStatus("Size of database file sent " + fileLength);
if(fileLength == fileSizeFromClient){
sendStatus("File sent to server, Successful");
returnInt = 1;
}else if(fileLength != fileSizeFromClient){
sendStatus("ERROR, file send failed");
returnInt = 2;
}
try {
dos.writeInt(returnInt);
} catch (IOException ex) {
Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
}
} // end run method
} // end of class comparefiles
public class CloseResources implements Runnable {
@Override
public void run() {
try {
fos.flush();
bis.close();
bos.close();
dis.close();
dos.close();
socket.close();
} catch (IOException ex) {
Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
}
} // end run method
} // end of class closeResources
public interface OnSendResultListener {
public void onStringResult(String transferString);
}
public void sendStatus(String status){
listener.onStringResult(status);
}
} // end class mulitthreader
编辑:这是第二次调用ConnectionUitlity对象的地方,在Multithreader类的构造函数中,当它被调用以在connectionUtility中创建一个新的多线程类时
public MultiThreader(Socket s) {
socket = s;
stpe = new ScheduledThreadPoolExecutor(5);
listener = ConnectionUtility.getInstance();
}
答案 0 :(得分:1)
来自评论
在多线程环境中,应同步getInstance
方法,或使用双重检查锁定。构造函数也应该是私有的,以避免在类之外创建。您应该查看http://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-with-examples