1

I want to make a singleton class Phone, so that it can be initializable (with number) and also concurrent-safe. So, here is what I came with:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;


public class PhoneTest {
    public static void main(String... args){
        System.out.println(Phone.getInstance().getNumber());
    }

    static final class Phone {
        private final String number;
        private final static Phone instance;
        static {
            instance = new Phone(PhonePropertyReader.readPhoneNumber());
        }

        private Phone(String number) {
            this.number = number;
        }

        public static Phone getInstance() {
            if (instance == null) throw 
                new IllegalStateException("instance was not initialized");
            return instance;
        }

        public String getNumber() {
            return number;
        }
    }


    static final class PhonePropertyReader {
        static String readPhoneNumber() {
            File file = new File("phone.properties");
            String phone = "";
            System.out.println(file.getAbsolutePath());
            if (!file.exists()) {
                return phone = "555-0-101";
            }

            try {
                BufferedReader r = new BufferedReader(new FileReader(file));
                phone = r.readLine().split("=")[1].trim();
                r.close();
            } catch (IOException e) {

            }
            return phone;
        }
    }
}

also I have a file phone.properties containing

phone=12345

Is it a good solution? Is it concurrent safe?

dhblah
  • 8,755
  • 9
  • 47
  • 81
  • 1
    Looks fine. You may want to [read this](http://blog.crazybob.org/2007/01/lazy-loading-singletons.html) and make your singleton lazy. – Boris the Spider Apr 14 '13 at 17:24
  • so it should be something like this: http://pastebin.com/sZAAMRur right? then I think that PhoneHolder will be loaded exactly at the same time as Phone is loaded, thus making Phone loading in this example to happen at the same time as my initial code. Am I correct? – dhblah Apr 14 '13 at 19:42
  • Yup, you're right. You example looks good. Except for the empty `catch` on line 50 - I would suggest you throw an [`ExceptionInInitializerError`](http://docs.oracle.com/javase/6/docs/api/java/lang/ExceptionInInitializerError.html). – Boris the Spider Apr 14 '13 at 20:17
  • thanks, but what about laziness? Am I correct that my initial code and the one I posted in a comment has the same "lazyness"? – dhblah Apr 14 '13 at 20:25

2 Answers2

1

I believe that Enum still the best way to implement thread-safe singletons in java.

Community
  • 1
  • 1
Salah Eddine Taouririt
  • 20,669
  • 14
  • 52
  • 83
0

I would discourage you to use singletons (Check this other question)

Otherwise, your code is thread-safe since the only affectation you do is in a static {} area which is, by definition, thread safe.

Btw, why not incorporate your readPhoneNumber() method directly in your phone class ?

Community
  • 1
  • 1
Nisalon
  • 215
  • 2
  • 10