import java.text.NumberFormat;
import java.util.Locale;

public class CompactFormatCloneTest {
    public static void main(String[] args) {

        // successful format loop does not use clone()
        for (int i = 0; i < 10; i++) {
            // give each thread a fresh copy of the format
            NumberFormat instance = createFormat();
            new Thread(new FormatTest(i, instance), "freshFormat " + i).start();
        }

        NumberFormat originalInstance = createFormat();

        // unsuccessful format loop using clone()
        for (int i = 0; i < 10; i++) {
            // give each thread a clone of the original
            NumberFormat instance = (NumberFormat) originalInstance.clone();
            new Thread(new FormatTest(i, instance), "formatClone " + i).start();
        }

        // unsuccessful parse loop using clone()
        for (int i = 0; i < 10; i++) {
            // give each thread a clone of the original
            NumberFormat instance = (NumberFormat) originalInstance.clone();
            new Thread(new ParseTest(i, instance), "parseClone " + i).start();
        }

    }


    public record FormatTest(int value, NumberFormat format) implements Runnable {

        @Override
        public void run() {
            String expected = String.valueOf(value);

            for (int i = 0; i < 1000; i++) {
                try {
                    String result = format.format(value);
                    if (!result.equals(expected)) {
                        System.out.println(Thread.currentThread().getName() + ": expected " + expected + " but got " + result);
                        break;
                    }
                } catch (Exception e) {
                    System.out.println(Thread.currentThread().getName() + ": exception" + e.getMessage());
                    break;
                }
            }
        }
    }

    public record ParseTest(int value, NumberFormat format) implements Runnable {

        @Override
        public void run() {
            String str = String.valueOf(value);

            for (int i = 0; i < 1000; i++) {
                try {
                    int result = format.parse(str).intValue();
                    if (result != value) {
                        System.out.println(Thread.currentThread().getName() + ": expected " + value + " but got " + result);
                        break;
                    }
                } catch (Exception e) {
                    System.out.println(Thread.currentThread().getName() + ": exception" + e.getMessage());
                    break;
                }
            }
        }
    }

    private static NumberFormat createFormat() {
        return NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
    }
}