-2

When I am using SimpleDateFormat on Android system, I found this error. 100 thread running simpleDateFormat.format(new Date(System.currentTimeMillis)),about 30 seconds latter, it will response error result, is their anyone tell me why. By the way the same code running on Jdk is not found this issue.

Below is my code

Utils.java

public class Utils {
public static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
public static BlockingQueue<String> msgQueue = new ArrayBlockingQueue<String>(100);

}

DateTimeRun.java

public class DateTimeRun implements Runnable {
private boolean running = true;
SimpleDateFormat simpleDateFormat = null;
BlockingQueue<String> queue;
public DateTimeRun(SimpleDateFormat sdf, BlockingQueue<String> queue){
    this.simpleDateFormat = sdf;
    this.queue = queue;
}
public void StopRunning(){
    this.running = false;
}

@Override
public void run() {
    while (this.running){
        Date d = new Date(System.currentTimeMillis());
        String msg = simpleDateFormat.format(d);
        if(msg.length()!=14){
            try {
                queue.put(msg);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

}

MainActivity.java

public class MainActivity extends AppCompatActivity {
public TextView textView = null;//(TextView)findViewById(R.id.txt_view);
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    initTask();
}

private void initTask(){
    textView = (TextView)findViewById(R.id.txt_view);
    Button button = (Button)findViewById(R.id.btn_Start);
    final Handler handler = new Handler(){
        public void handleMessage(Message msg){
            switch (msg.what){
                case 1:
                    Bundle bundle = msg.getData();
                    String m = bundle.getString("datetimemsg");
                    m = String.format("%s\n%s",m,MainActivity.this.textView.getText().toString());
                    MainActivity.this.textView.setText(m);
                    break;
            }
            super.handleMessage(msg);
        }
    };

    button.setOnClickListener(new View.OnClickListener(){

        @Override
        public void onClick(View view) {
            //textView.setText("aaaa");
            final List<DateTimeRun> runList = new ArrayList<DateTimeRun>();
            for(int i=0;i<100;i++) {
                runList.add(new DateTimeRun(Utils.simpleDateFormat, Utils.msgQueue));
            }
            for(DateTimeRun dtr:runList){
                Thread t = new Thread(dtr);
                t.start();
            }

            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    int times = 10;
                    while(times>0){
                        try {
                            times--;
                            String msg = Utils.msgQueue.take();
                            Message message = new Message();
                            message.what = 1;
                            Bundle data = new Bundle();
                            data.putString("datetimemsg",msg);
                            message.setData(data);
                            handler.sendMessage(message);
                            System.out.println(msg);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    for(DateTimeRun t: runList){
                        t.StopRunning();
                    }
                }
            });
            thread.start();
        }
    });
}

This is The System out result:

I/System.out: 2016121816400002

I/System.out: 2016120018164003

I/System.out: 2016121816004003

I/System.out: 2016001218164004

I/System.out: 2016121816400004

I/System.out: 2016121800164005

I/System.out: 2016120018164005

I/System.out: 2016121816004006

I/System.out: 2016120018164007

I/System.out: 2016001218164009

This is the cut image: the result of formated datetime length is not 14

1 Answers1

1

SimpleDateFormat is not thread-safe.

You can't create a single instance of it and re-use across threads, instead, create a new SimpleDateFormat whenever you need one.

See: https://stackoverflow.com/a/6840856/819355

Community
  • 1
  • 1
marmor
  • 25,207
  • 10
  • 99
  • 145