java – 没有print语句就没有执行代码

前端之家收集整理的这篇文章主要介绍了java – 没有print语句就没有执行代码前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
参见英文答案 > Loop doesn’t see changed value without a print statement1个
我一直在制作倒计时节目,我想出了这个.
  1. package main;
  2.  
  3. import java.awt.FlowLayout;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. import java.io.File;
  7. import java.io.IOException;
  8. import java.net.MalformedURLException;
  9.  
  10. import javax.sound.sampled.AudioInputStream;
  11. import javax.sound.sampled.AudioSystem;
  12. import javax.sound.sampled.Clip;
  13. import javax.sound.sampled.DataLine;
  14. import javax.sound.sampled.LineUnavailableException;
  15. import javax.sound.sampled.UnsupportedAudioFileException;
  16. import javax.swing.JButton;
  17. import javax.swing.JFrame;
  18. import javax.swing.JLabel;
  19. import javax.swing.JTextField;
  20.  
  21. public class Gatoo extends JFrame implements ActionListener {
  22. private int sec,min,secTot,since = 999;
  23. private long lastTime;
  24.  
  25. private JTextField mm = new JTextField(2),ss = new JTextField(2);
  26. private JLabel minLab = new JLabel("Minutes:"),secLab = new JLabel(
  27. "Seconds:");
  28. private JButton start = new JButton("Start");
  29.  
  30. private Clip done;
  31. private boolean started = false;
  32.  
  33. private static final long serialVersionUID = 4277921337939922028L;
  34.  
  35. public static void main(String[] args) {
  36. Gatoo cake = new Gatoo("Title");
  37. cake.pack();
  38. cake.setSize(800,600);
  39. cake.setLocationRelativeTo(null);
  40. cake.setDefaultCloSEOperation(3);
  41. cake.setVisible(true);
  42. cake.run();
  43. }
  44.  
  45. public Gatoo(String s) {
  46. super(s);
  47. setLayout(new FlowLayout());
  48.  
  49. start.addActionListener(this);
  50.  
  51. add(minLab);
  52. add(mm);
  53. add(secLab);
  54. add(ss);
  55. add(start);
  56. }
  57.  
  58. @Override
  59. public void actionPerformed(ActionEvent e) {
  60. started = true;
  61. }
  62.  
  63. public void play(File file) throws MalformedURLException,UnsupportedAudioFileException,IOException,LineUnavailableException {
  64. AudioInputStream ais = AudioSystem.getAudioInputStream(new File(
  65. "lib/done.wav"));
  66. DataLine.Info info = new DataLine.Info(Clip.class,ais.getFormat());
  67. done = (Clip) AudioSystem.getLine(info);
  68. done.open(ais);
  69. done.start();
  70. }
  71.  
  72. public void run() {
  73. while (true) {
  74. System.out.print("");// needed?
  75. if (started) {
  76. try {
  77. min = Integer.parseInt(mm.getText());
  78. sec = Integer.parseInt(ss.getText());
  79. secTot = (min * 60) + sec;
  80. lastTime = System.currentTimeMillis();
  81. while (secTot > 0) {
  82. since = (int) (System.currentTimeMillis() - lastTime);
  83. if (since > 998) {
  84. lastTime = System.currentTimeMillis();
  85. secTot--;
  86. }
  87. }
  88.  
  89. play(new File("done.wav"));
  90.  
  91. } catch (NumberFormatException exception) {
  92. System.out.println("Minutes and seconds must be numbers.");
  93. return;
  94. } catch (Exception exception) {
  95. exception.printStackTrace();
  96. }
  97. started = false;
  98. }
  99. }
  100. }
  101. }

在最后的while循环中,如果没有print / println语句,倒计时代码就不会执行.怎么会?尽管如此,该程序与print语句完美配合.

解决方法

首先,您的程序是线程不安全的,因为boolean started是一个共享变量,但它既不易变,也不在synchronized块中访问.

现在,意外地,PrintStream #print是一种同步方法,并且在任何实际架构上,使用内存屏障cpu指令实现进入和退出同步块,这导致线程本地状态和主内存之间的完全同步.

因此,通过纯事故,添加打印调用允许一个线程(EDT)的启动标志的设置被另一个(主线程)可见.

猜你在找的Java相关文章