问题描述
引用SageZk的代码做了个计时器,现在想读取从开始到结束的每一个时间,比如0.000,0.001,0.002,0.003。。。但发现用了System.nanoTime()之后,还是有一些时间丢失了,这是什么原因呢?该如何解决?publicclassnanoTimeframeextendsJFrame{//privatelongtime=(long)(0.3*60*1000L);//倒计时时间(单位毫秒)privatelongtime=(long)(10*1000L);privateJLabellblTime;privateThreadrunner;publicnanoTimeframe(){super("nanoTimeframe");this.lblTime=newJLabel("单击开始");this.lblTime.setFont(newFont("Monospaced",Font.BOLD,60));this.lblTime.setHorizontalAlignment(SwingConstants.CENTER);this.lblTime.addMouseListener(newMouseAdapter(){publicvoidmouseClicked(MouseEvente){if(runner!=null)runner.start();}});this.runner=newThread(newRunnable(){publicvoidrun(){Datet=newDate();StringWritersw=newStringWriter();StringBuffersb=sw.getBuffer();PrintWriterpw=newPrintWriter(sw);longcur=0L,start=System.nanoTime()/1000000L,end=System.currentTimeMillis()+time;System.out.println(time);while((cur=System.nanoTime()/1000000L-start)<=time){t.setTime(cur);System.out.println(cur);pw.format("%1$tM:%1$tS.%tL",t);pw.flush();lblTime.setText(sb.toString());/*sb.setLength(0);try{Thread.sleep(1L);}catch(InterruptedExceptione){}*/}lblTime.setText("00:00.000");try{Thread.sleep(1200L);}catch(InterruptedExceptione){}lblTime.setText("Bomb!!!");}});this.runner.setDaemon(true);getContentPane().add(this.lblTime,BorderLayout.CENTER);setResizable(false);setBounds(0,0,460,330);setLocationRelativeTo(null);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}publicstaticvoidmain(String[]args){newTimerFrame().setVisible(true);}}
解决方案
解决方案二:
求解答啊。。是不是在windows系统做不到啊?
解决方案三:
改造了下你代码,不知道是不是你想要的!importjava.awt.BorderLayout;importjava.awt.Font;importjava.awt.Graphics;importjava.awt.event.MouseAdapter;importjava.awt.event.MouseEvent;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JPanel;importjavax.swing.SwingConstants;publicclassNanoTimeframeextendsJPanel{privatestaticfinallongserialVersionUID=-6135068834705503622L;privateJLabellblTime;privatelongstart=0L;//从0毫秒开始privatefinallongMAXTIME=5000L;//5秒后结束privatebooleanbegin=false;publicNanoTimeframe(){this.lblTime=newJLabel("单击开始");this.lblTime.setFont(newFont("Monospaced",Font.BOLD,60));this.lblTime.setHorizontalAlignment(SwingConstants.CENTER);this.lblTime.addMouseListener(newMouseAdapter(){publicvoidmouseClicked(MouseEvente){begin=true;lblTime.setText(timeStr(start));}});setLayout(newBorderLayout());add(lblTime,BorderLayout.CENTER);}privateStringtimeStr(longtime){StringBuffertimeBuffer=newStringBuffer();longmiu=time/(60*1000);time-=miu*60*1000;longse=time/1000;time-=se*1000;longmi=time%1000;timeBuffer.append(miu<10?("0"+miu):miu);timeBuffer.append(".");timeBuffer.append(se<10?("0"+se):se);timeBuffer.append(".");timeBuffer.append(mi<10?("00"+mi):(mi<100?("0"+mi):mi));returntimeBuffer.toString();}@OverridepublicvoidpaintComponent(Graphicspage){if(!begin)return;super.paintComponent(page);if(start>=MAXTIME){lblTime.setText("Bomb!!!");return;}start+=1;lblTime.setText(timeStr(start));}publicstaticvoidmain(String[]args){JFramejf=newJFrame();jf.setResizable(false);jf.setBounds(0,0,460,330);jf.setLocationRelativeTo(null);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jf.add(newNanoTimeframe());jf.setVisible(true);}}
解决方案四:
任何现代的操作系统都做不到连操作系统自身都不能做到,别说你一个应用程序了。
解决方案五:
就是这样子的!这个是用系统的时间吗?@maihao110
解决方案六:
是不是不能用系统的时间?系统的都有误差吗?
解决方案七:
系统时间版本!肯定有误差!importjava.awt.BorderLayout;importjava.awt.Font;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.awt.event.MouseAdapter;importjava.awt.event.MouseEvent;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JPanel;importjavax.swing.SwingConstants;importjavax.swing.Timer;publicclassNanoTimeframeextendsJPanel{privatestaticfinallongserialVersionUID=-6135068834705503622L;privateJLabellblTime;privatelongstart=0L;//从0毫秒开始privatefinallongMAXTIME=5000L;//5秒后结束privateTimertimer;privatefinalintDEDLY=0;privatelongsTime;privatelongeTime;publicNanoTimeframe(){timer=newTimer(DEDLY,newActionListener(){@OverridepublicvoidactionPerformed(ActionEvente){if(start>=MAXTIME){eTime=System.currentTimeMillis();System.out.println("误差:"+(eTime-sTime-MAXTIME)+"毫秒");timer.stop();lblTime.setText("Bomb!!!");return;}start+=1;lblTime.setText(timeStr(start));}});this.lblTime=newJLabel("单击开始");this.lblTime.setFont(newFont("Monospaced",Font.BOLD,60));this.lblTime.setHorizontalAlignment(SwingConstants.CENTER);this.lblTime.addMouseListener(newMouseAdapter(){publicvoidmouseClicked(MouseEvente){lblTime.setText(timeStr(start));timer.start();sTime=System.currentTimeMillis();}});setLayout(newBorderLayout());add(lblTime,BorderLayout.CENTER);}privateStringtimeStr(longtime){StringBuffertimeBuffer=newStringBuffer();longmiu=time/(60*1000);time-=miu*60*1000;longse=time/1000;time-=se*1000;longmi=time%1000;timeBuffer.append(miu<10?("0"+miu):miu);timeBuffer.append(".");timeBuffer.append(se<10?("0"+se):se);timeBuffer.append(".");timeBuffer.append(mi<10?("00"+mi):(mi<100?("0"+mi):mi));returntimeBuffer.toString();}publicstaticvoidmain(String[]args){JFramejf=newJFrame();jf.setResizable(false);jf.setBounds(0,0,460,330);jf.setLocationRelativeTo(null);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jf.add(newNanoTimeframe());jf.setVisible(true);}}
解决方案八:
噢,如果换成nanotime会不会误差小一点?只要求误差在一毫秒之内就可以了。。@maihao110
解决方案九:
引用7楼tanweijia888的回复:
噢,如果换成nanotime会不会误差小一点?只要求误差在一毫秒之内就可以了。。@maihao110
1nano的误差确实会小点2但是也没法保证,因为有可能CPU被其他应用的频繁内存同步或者其他大的开销,导致你当前进程分配更少的CPU时间,一般,现在的PC来说毫秒级的精确很难做到。10毫秒级貌似还是可能的。
解决方案十:
引用8楼shine333的回复:
Quote: 引用7楼tanweijia888的回复:
噢,如果换成nanotime会不会误差小一点?只要求误差在一毫秒之内就可以了。。@maihao1101nano的误差确实会小点2但是也没法保证,因为有可能CPU被其他应用的频繁内存同步或者其他大的开销,导致你当前进程分配更少的CPU时间,一般,现在的PC来说毫秒级的精确很难做到。10毫秒级貌似还是可能的。
噢,好的~唉,现在在处理一个文件,无线网之间的传输,这些包的收发时间都是纳秒级别的啊。。不知道咋办了,
解决方案十一:
引用2楼maihao110的回复:
改造了下你代码,不知道是不是你想要的!importjava.awt.BorderLayout;importjava.awt.Font;importjava.awt.Graphics;importjava.awt.event.MouseAdapter;importjava.awt.event.MouseEvent;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JPanel;importjavax.swing.SwingConstants;publicclassNanoTimeframeextendsJPanel{privatestaticfinallongserialVersionUID=-6135068834705503622L;privateJLabellblTime;privatelongstart=0L;//从0毫秒开始privatefinallongMAXTIME=5000L;//5秒后结束privatebooleanbegin=false;publicNanoTimeframe(){this.lblTime=newJLabel("单击开始");this.lblTime.setFont(newFont("Monospaced",Font.BOLD,60));this.lblTime.setHorizontalAlignment(SwingConstants.CENTER);this.lblTime.addMouseListener(newMouseAdapter(){publicvoidmouseClicked(MouseEvente){begin=true;lblTime.setText(timeStr(start));}});setLayout(newBorderLayout());add(lblTime,BorderLayout.CENTER);}privateStringtimeStr(longtime){StringBuffertimeBuffer=newStringBuffer();longmiu=time/(60*1000);time-=miu*60*1000;longse=time/1000;time-=se*1000;longmi=time%1000;timeBuffer.append(miu<10?("0"+miu):miu);timeBuffer.append(".");timeBuffer.append(se<10?("0"+se):se);timeBuffer.append(".");timeBuffer.append(mi<10?("00"+mi):(mi<100?("0"+mi):mi));returntimeBuffer.toString();}@OverridepublicvoidpaintComponent(Graphicspage){if(!begin)return;super.paintComponent(page);if(start>=MAXTIME){lblTime.setText("Bomb!!!");return;}start+=1;lblTime.setText(timeStr(start));}publicstaticvoidmain(String[]args){JFramejf=newJFrame();jf.setResizable(false);jf.setBounds(0,0,460,330);jf.setLocationRelativeTo(null);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jf.add(newNanoTimeframe());jf.setVisible(true);}}
那能不能把这个计时器的时间作为程序的系统时间。比如要实现车在走的动画,而行走时间什么的按照这个计时器的来弄。那这个计时器应该放在哪里呢?
解决方案十二:
引用9楼tanweijia888的回复:
噢,好的~唉,现在在处理一个文件,无线网之间的传输,这些包的收发时间都是纳秒级别的啊。。不知道咋办了,
你不是要倒计时啊,你到底要什么?说具体点,我可能被你误导了!
解决方案十三:
引用11楼maihao110的回复:
Quote: 引用9楼tanweijia888的回复:
噢,好的~唉,现在在处理一个文件,无线网之间的传输,这些包的收发时间都是纳秒级别的啊。。不知道咋办了,你不是要倒计时啊,你到底要什么?说具体点,我可能被你误导了!
要处理一个文件需要弄一个正计时器,精确到毫秒。。那些文件数据是这样的:r0.001408067_1_RTR---0AODV48[0ffffffff0800]-------[0:255-1:255300][0x211[10][04]](REQUEST)s0.001408067_1_RTR---0AODV44[0000]-------[1:2550:255300][0x41[14]10.000000](REPLY)s0.003200000_0_AGT---1cbr200[0000]-------[0:01:0320][1]00第一列“r”“s”表示发送或者接收这个包,第二列表示发送或者接收的时间!第三列“_0_”"_1_"表示参与的节点。现在想弄一个计时器从0开始,判断当计时到比如0.001408067这个时间时,就把这一行后面的数据提取出来!因为精确度到不了纳秒,所以想把时间取前三位小数,弄成毫秒的。。比如这几个时间就变成”0.001“秒,”0.001“秒,”0.003“秒。要求这个计时器能取到从”0.000“秒到最后时间的所有时间,间隔一毫秒!大概就是想要达到这种效果。。
解决方案十四:
求解答啊!@maihao110
解决方案十五:
引用13楼tanweijia888的回复:
求解答啊!@maihao110
你提前把文件读入内存了!定时器只是走到特定时间取内存中的数据。这我觉得完全可以精确到1毫秒以内。但是你这文件提前生成了。。你再做个定时器,取特定时间数据??这有意义吗?
解决方案:
引用14楼maihao110的回复:
Quote: 引用13楼tanweijia888的回复:
求解答啊!@maihao110你提前把文件读入内存了!定时器只是走到特定时间取内存中的数据。这我觉得完全可以精确到1毫秒以内。但是你这文件提前生成了。。你再做个定时器,取特定时间数据??这有意义吗?
其实就是想把这个文件的数据提取出来做一个发送接收包的动画效果,定时器走到特定时间把该行数据提取出来然后做动画。我现在写的程序已经实现读取数据了,那这个数据是算读入内存吧?问题就是用系统时间做的定时器都会有些时间提取不出来做不了判断。。还有就是假如用你之前的那个手动加1的定时器时间作为动画效果程序的时间,这样可行吗?