我终于能够在你们提出一些很好的建议之后让我的线程恢复,但我无法阻止它......它似乎仍然被锁定但是我无法让它优雅地停止。这是全班,所以你可以运行它。我很亲密......我想。我已经注释了我在跑步和停止方法中的尝试
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package treadmakestop;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
*
* @author brett
*/
public class WorkFile {
public static void main(String[] args) {
WorkFile workFile = new WorkFile();
}
public WorkFile() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
}
JFrame frame = new JFrame("TvCOnvert");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TvGui());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setSize(350, 100);
frame.setResizable(false);
frame.setVisible(true);
}
});
}
public class TvGui extends JPanel {
private JProgressBar tvpb;
private JButton startButton;
private JButton cancelButton;
private JButton exitButton;
private Worker worker;
private Thread t;
public TvGui() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.NORTHWEST;
startButton = new JButton();
startButton.setText("Start");
gbc.insets = new Insets(10, 5, 0, 0);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.weightx = 0.5;
add(startButton, gbc);
cancelButton = new JButton();
gbc.insets = new Insets(10, 0, 0, 0);
gbc.gridx = 2;
gbc.gridy = 2;
gbc.weightx = 0.5;
cancelButton.setText("Cancel");
add(cancelButton, gbc);
exitButton = new JButton();
gbc.insets = new Insets(10, 0, 0, 5);
gbc.gridx = 3;
gbc.gridy = 2;
gbc.weightx = 0.5;
exitButton.setText("Exit");
add(exitButton, gbc);
tvpb = new JProgressBar();
tvpb.setBorderPainted(true);
tvpb.setStringPainted(true);
gbc.insets = new Insets(5, 5, 0, 5);
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.gridx = 1;
gbc.gridy = 3;
gbc.gridwidth = 3;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.BASELINE;
add(tvpb, gbc);
tvpb.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
System.out.println(tvpb.getValue());
if (tvpb.getValue() >= 100) {
worker = null;
}
}
});
tvpb.addPropertyChangeListener("value", new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
}
});
startButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (worker == null) {
worker = new Worker(tvpb);
t = new Thread(worker);
t.start();
}
}
});
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
worker.pause();
tvpb.setIndeterminate(true);
int n = JOptionPane.showConfirmDialog(
null,
"Sure you want to delete this process?",
"Kill Operation",
JOptionPane.YES_NO_OPTION);
if (n == JOptionPane.YES_OPTION) {
worker.stop();
//t.interrupt();
//worker = null;
tvpb.setIndeterminate(false);
tvpb.setValue(0);
} else if (n == JOptionPane.NO_OPTION) {
tvpb.setIndeterminate(false);
worker.resume();
}
}
});
exitButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
}
}
public class Worker implements Runnable {
TvGui gu = new TvGui();
private ReentrantLock pauseLock;
private Condition pauseCondition;
private AtomicBoolean paused;
private JProgressBar tvpg;
public Worker(JProgressBar tvpg) {
paused = new AtomicBoolean();
pauseLock = new ReentrantLock();
pauseCondition = pauseLock.newCondition();
this.tvpg = tvpg;
}
public void pause() {
paused.set(true);
}
public void resume() {
paused.set(false);
pauseLock.lock();
try {
pauseCondition.signal();
} finally {
pauseLock.unlock();
}
}
public synchronized void stop(){
try {
// gu.t = null;
// gu.t.interrupt();
//Thread thr = Thread.currentThread();
System.out.println("Thread name is:"+" "+gu.t.getName());
Thread.currentThread().interrupt();
} catch (Exception e) {
}
}
private volatile boolean threadSuspended;
@Override
public void run() {
Thread thisThread = Thread.currentThread();
while ( gu.t == thisThread) {
try {
Thread.sleep(1);
synchronized(this) {
while (threadSuspended && gu.t ==thisThread)
wait();
}
} catch (InterruptedException e){
}
}
int times = 100_000;
for (int i = 0; i <= times; i++) {
checkPauseState();
updateProgress(Math.round((i / (float) times) * 100f));
try {
Thread.sleep(1);
} catch (InterruptedException ex) {
}
}
}
protected void checkPauseState() {
while (paused.get()) {
pauseLock.lock();
try {
pauseCondition.await();
} catch (Exception e) {
} finally {
pauseLock.unlock();
}
}
}
protected void updateProgress(int progress) {
if (EventQueue.isDispatchThread()) {
tvpg.setValue(progress);
} else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
updateProgress(progress);
}
});
}
}
public boolean isPaused() {
return paused.get();
}
}
}
答案 0 :(得分:2)
除非您实际检查当前线程的intrrupted
状态,否则中断它将无效...
相反,您可以使用另一个AtomicBoolean
值来指示线程是否应该继续执行它的工作,例如
public class Worker implements Runnable {
//...
private AtomicBoolean keepRunning;
public Worker(JProgressBar tvpg) {
//...
keepRunning = new AtomicBoolean(true);
//...
}
//...
public synchronized void stop() {
keepRunning.set(false);
// Make sure the thread isn't currently
// paused, otherwise it will never exit...
resume();
}
//...
@Override
public void run() {
System.out.println("Runnable has started");
int times = 100_000;
int i = 0;
while (i < times && keepRunning.get()) {
checkPauseState();
updateProgress(Math.round((i / (float) times) * 100f));
try {
Thread.sleep(1);
} catch (InterruptedException ex) {
}
i++;
}
System.out.println("Runnable has exited");
}
我们在run
方法中更改循环以适应新的退出条件......
for (int i = 0; i < times && keepRunning.get(); i++) {
checkPauseState();
updateProgress(Math.round((i / (float) times) * 100f));
try {
Thread.sleep(1);
} catch (InterruptedException ex) {
}
}
完整的事情......
public class Worker implements Runnable {
private ReentrantLock pauseLock;
private Condition pauseCondition;
private AtomicBoolean paused;
private AtomicBoolean keepRunning;
private JProgressBar tvpg;
public Worker(JProgressBar tvpg) {
paused = new AtomicBoolean();
keepRunning = new AtomicBoolean(true);
pauseLock = new ReentrantLock();
pauseCondition = pauseLock.newCondition();
this.tvpg = tvpg;
}
public void pause() {
paused.set(true);
}
public void resume() {
paused.set(false);
pauseLock.lock();
try {
pauseCondition.signal();
} finally {
pauseLock.unlock();
}
}
public synchronized void stop() {
keepRunning.set(false);
resume();
}
@Override
public void run() {
System.out.println("Runnable has started");
int times = 100_000;
int i = 0;
while (i < times && keepRunning.get()) {
checkPauseState();
updateProgress(Math.round((i / (float) times) * 100f));
try {
Thread.sleep(1);
} catch (InterruptedException ex) {
}
i++;
}
System.out.println("Runnable has exited");
}
protected void checkPauseState() {
while (paused.get()) {
pauseLock.lock();
try {
pauseCondition.await();
} catch (Exception e) {
} finally {
pauseLock.unlock();
}
}
}
protected void updateProgress(int progress) {
if (EventQueue.isDispatchThread()) {
tvpg.setValue(progress);
} else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
updateProgress(progress);
}
});
}
}
public boolean isPaused() {
return paused.get();
}
}
另一个解决方案是获得state
值,该值确定Worker
类的当前值
public static class Worker implements Runnable {
public enum State {
RUNNING,
PAUSED,
NOT_STARTED,
STOPPPED,
COMPLETED;
}
private volatile State state = State.NOT_STARTED;
这为您提供了有关Worker
当前状态的更多信息,以及有关如何完成(自然完成或是否已停止)的信息,例如......
public static class Worker implements Runnable {
public enum State {
RUNNING,
PAUSED,
NOT_STARTED,
STOPPPED,
COMPLETED;
}
private volatile State state = State.NOT_STARTED;
private ReentrantLock pauseLock;
private Condition pauseCondition;
private JProgressBar tvpg;
public Worker(JProgressBar tvpg) {
pauseLock = new ReentrantLock();
pauseCondition = pauseLock.newCondition();
this.tvpg = tvpg;
}
public void pause() {
if (state == State.RUNNING) {
state = State.PAUSED;
}
}
public void resume() {
if (state == State.PAUSED || state == State.STOPPPED) {
if (state == State.PAUSED) {
state = State.RUNNING;
}
pauseLock.lock();
try {
pauseCondition.signal();
} finally {
pauseLock.unlock();
}
}
}
public synchronized void stop() {
state = State.STOPPPED;
resume();
}
@Override
public void run() {
state = State.RUNNING;
System.out.println("Runnable has started");
int times = 100_000;
for (int i = 0; i < times && state != State.STOPPPED; i++) {
checkPauseState();
updateProgress(Math.round((i / (float) times) * 100f));
try {
Thread.sleep(1);
} catch (InterruptedException ex) {
}
}
if (state != State.STOPPPED) {
state = State.COMPLETED;
}
System.out.println("Runnable has exited");
}
protected void checkPauseState() {
while (state == State.PAUSED) {
pauseLock.lock();
try {
pauseCondition.await();
} catch (Exception e) {
} finally {
pauseLock.unlock();
}
}
}
protected void updateProgress(int progress) {
if (EventQueue.isDispatchThread()) {
tvpg.setValue(progress);
} else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
updateProgress(progress);
}
});
}
}
public boolean isPaused() {
return state == State.PAUSED;
}
public boolean isRunning() {
return state == State.RUNNING;
}
public boolean wasStopped() {
return state == State.STOPPPED;
}
public boolean didComplete() {
return state == State.COMPLETED;
}
}
这取消了AtomicBoolean
变量支持state
变量...作为另一个想法