[英]Looking to pause a thread using thread.sleep
我正在使用鼠標偵聽器來按下和釋放鼠標。 按下鼠標時,我想讓計數器增加一個變量,釋放鼠標時,我要減少該變量。 現在,我的代碼可以正常工作,但是這樣做的速度太快了,我想減慢速度,因為我將這些數字用作游戲中的坐標。 我嘗試添加Thread.sleep(100),但是輸出偏斜。 似乎有多個線程同時出現,並且到處都是數字。 下面是示例代碼。
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.event.*;
import java.awt.event.ActionListener;
import java.lang.*;
public class Sample extends JFrame {
private JPanel jp = new JPanel();
int i = 0;
boolean once = true;
boolean on = true;
Thread t1 = new Thread(new Increase());
Thread t2 = new Thread(new Decrease());
public sample() {
setVisible(true);
setSize(300, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(jp);
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent event) {
if (!once) //false
{
t2.interrupt();
}
if (once) //true
{
once = false;
t1.start();
}
else {
t1 = new Thread(new Increase());
t1.start();
}
}
public void mouseReleased(MouseEvent event) {
t1.interrupt();
if (on) //true
{
on = false;
t2.start();
}
else {
t2 = new Thread(new Decrease());
t2.start();
}
}
});
}
public static void main(String[] args) {
new Sample();
}
public int getI() {
return i;
}
public void setI(int num) {
i = num;
}
class Increase implements Runnable {
public void run() {
int num = getI();
while (!Thread.currentThread().isInterrupted()) {
try {
setI(++num);
Thread.sleep(100);
System.out.println(num);
}
catch (InterruptedException e) {
}
}
}
}
//Thread.currentThread().isInterrupted()
class Decrease implements Runnable {
public void run() {
int num = getI();
while (!Thread.currentThread().isInterrupted()) {
try {
setI(--num);
Thread.sleep(100);
System.out.println(num);
}
catch (InterruptedException e) {
}
}
}
}
}
你可能運行到兩個線程之間的競爭條件,事實上, i
是不揮發也表明線程可能不相同的實際值相互合作。
線程也是不可重入的,這意味着一旦存在run
方法,就無法重新啟動它們。
您只需使用一個Thread
和一個“增量”(或更改)值即可達到相同的結果。
以下示例使用了Swing Timer
,因為它更簡單,並且允許我安全地更新UI,但是原理是相同的。
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel label;
private Timer timer;
private int value = 0;
private int delta = 1;
public TestPane() {
setLayout(new GridBagLayout());
label = new JLabel("0");
add(label);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
delta *= -1;
}
@Override
public void mouseReleased(MouseEvent e) {
delta *= -1;
}
});
timer = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setValue(getValue() + delta);
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
label.setText(Integer.toString(value));
}
}
}
只是因為我完全瘋了,很高興演示額外的工作量。 本示例使用兩個Thread
。
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel implements Value {
private JLabel label;
private volatile int value = 0;
private ManipulateRunner incrementRunner;
private ManipulateRunner decrementRunner;
private Thread incrementThread;
private Thread decrementThread;
public TestPane() {
incrementRunner = new ManipulateRunner(this, 1);
decrementRunner = new ManipulateRunner(this, -1);
setLayout(new GridBagLayout());
label = new JLabel("0");
add(label);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
decrementRunner.pause();
if (incrementThread == null) {
incrementThread = new Thread(incrementRunner);
incrementThread.start();
}
incrementRunner.resume();
}
@Override
public void mouseReleased(MouseEvent e) {
incrementRunner.pause();
if (decrementThread == null) {
decrementThread = new Thread(decrementRunner);
decrementThread.start();
}
decrementRunner.resume();
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
public int getValue() {
return value;
}
@Override
public void setValue(final int value) {
if (EventQueue.isDispatchThread()) {
this.value = value;
label.setText(Integer.toString(value));
} else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setValue(value);
}
});
}
}
}
public static interface Value {
public int getValue();
public void setValue(int value);
}
public static class ManipulateRunner implements Runnable {
protected final Object pauseLock = new Object();
private int delta;
private AtomicBoolean paused = new AtomicBoolean(false);
private AtomicBoolean stopped = new AtomicBoolean(false);
private Value value;
public ManipulateRunner(Value value, int delta) {
this.delta = delta;
this.value = value;
}
public void pause() {
if (!paused.get() && !stopped.get()) {
paused.set(true);
synchronized (pauseLock) {
pauseLock.notify();
}
}
}
public void resume() {
if (paused.get() && !stopped.get()) {
paused.set(false);
synchronized (pauseLock) {
pauseLock.notify();
}
}
}
public void stop() {
if (!stopped.get()) {
stopped.set(true);
synchronized (pauseLock) {
pauseLock.notify();
}
}
}
@Override
public void run() {
while (!stopped.get()) {
while (!stopped.get() && paused.get()) {
synchronized (pauseLock) {
try {
pauseLock.wait();
} catch (InterruptedException ex) {
}
}
}
if (!stopped.get()) {
value.setValue(value.getValue() + delta);
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
}
}
}
}
}
就個人而言,最簡單有效的解決方案是更好的解決方案,但這就是我
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.