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
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