如何从另一个线程暂停和恢复Java中的线程

我正在用Java Swing编写应用程序。我需要的是一个可以使用图形界面中的按钮停止“阐述”线程的过程。

这里有一个简单的项目专注于我的需求

import java.util.logging.Level;

import java.util.logging.Logger;

import javax.swing.JTextArea;

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

/**

*

* @author Nikola

*/

public class Main extends javax.swing.JFrame

{

private MyThread THREAD;

public Main()

{

initComponents();

}

@SuppressWarnings("unchecked")

// <editor-fold defaultstate="collapsed" desc="Generated Code">

private void initComponents() {

jButton1 = new javax.swing.JButton();

jScrollPane1 = new javax.swing.JScrollPane();

jTextArea1 = new javax.swing.JTextArea();

jButton2 = new javax.swing.JButton();

jButton3 = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

jButton1.setText("Pause Thread");

jButton1.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent evt) {

jButton1ActionPerformed(evt);

}

});

jTextArea1.setColumns(20);

jTextArea1.setRows(5);

jScrollPane1.setViewportView(jTextArea1);

jButton2.setText("Resume Thread");

jButton2.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent evt) {

jButton2ActionPerformed(evt);

}

});

jButton3.setText("Start Thread");

jButton3.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent evt) {

jButton3ActionPerformed(evt);

}

});

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());

getContentPane().setLayout(layout);

layout.setHorizontalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addContainerGap()

.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addComponent(jButton3)

.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 63, Short.MAX_VALUE)

.addComponent(jButton2)

.addGap(18, 18, 18)

.addComponent(jButton1))

.addComponent(jScrollPane1))

.addContainerGap())

);

layout.setVerticalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()

.addContainerGap()

.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 244, Short.MAX_VALUE)

.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)

.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)

.addComponent(jButton1)

.addComponent(jButton2)

.addComponent(jButton3))

.addContainerGap())

);

pack();

}// </editor-fold>

private void jButton3ActionPerformed(java.awt.event.ActionEvent evt)

{

THREAD = new MyThread(jTextArea1);

THREAD.start();

}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)

{

try

{

THREAD.pauseThread();

}

catch (InterruptedException ex)

{

ex.printStackTrace();

}

}

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt)

{

THREAD.resumeThread();

}

public static void main(String args[])

{

/*

* Set the Nimbus look and feel

*/

//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">

/*

* If Nimbus (introduced in Java SE 6) is not available, stay with the

* default look and feel. For details see

* http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html

*/

try

{

for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())

{

if ("Nimbus".equals(info.getName()))

{

javax.swing.UIManager.setLookAndFeel(info.getClassName());

break;

}

}

}

catch (ClassNotFoundException ex)

{

java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);

}

catch (InstantiationException ex)

{

java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);

}

catch (IllegalAccessException ex)

{

java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);

}

catch (javax.swing.UnsupportedLookAndFeelException ex)

{

java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);

}

//</editor-fold>

/*

* Create and display the form

*/

java.awt.EventQueue.invokeLater(new Runnable()

{

public void run()

{

new Main().setVisible(true);

}

});

}

// Variables declaration - do not modify

private javax.swing.JButton jButton1;

private javax.swing.JButton jButton2;

private javax.swing.JButton jButton3;

private javax.swing.JScrollPane jScrollPane1;

private javax.swing.JTextArea jTextArea1;

// End of variables declaration

}

class MyThread extends Thread

{

JTextArea area;

private final Object lock = new Object();

public MyThread(JTextArea area)

{

super();

this.area = area;

}

@Override

public void run()

{

for(int i=0 ; ; i++)

area.setText(i+"");

}

public void pauseThread() throws InterruptedException

{

synchronized(lock)

{

lock.wait();

}

}

public void resumeThread()

{

synchronized(lock)

{

lock.notify();

}

}

}

问题很简单:在实际的应用程序中,用户设置一些选项,然后启动线程,对选定的数据进行详细说明。

我想提供一个“暂停”按钮,以便用户可以暂时停止详细说明并进行必要的检查,然后可以恢复操作。

我编码的方式是停止的图形线程,而不是“精化”线程。

如果运行示例代码并按“开始”,则文本区域开始计数。我需要的最终结果是,当我按下“暂停”按钮时,线程进入“睡眠”状态,计数停止;当我按下“恢复”按钮时,线程“唤醒”,文本区域中的计数开始再数一次。

回答:

您无法按照您想要的方式 最终 从另一个线程中暂停一个线程。

您需要做的是通过设置某种标志来 通知 另一个线程应该停止。有问题的线程必须具有检查该标志并在发生这种情况时暂停其工作的逻辑。

因此,在这种特殊情况下,可能MyThread如下更改:

class MyThread extends Thread {

private volatile boolean running = true; // Run unless told to pause

...

@Override

public void run()

{

for(int i=0 ; ; i++)

{

// Only keep painting while "running" is true

// This is a crude implementation of pausing the thread

while (!running)

yield;

area.setText(i+"");

}

public void pauseThread() throws InterruptedException

{

running = false;

}

public void resumeThread()

{

running = true;

}

}

这是一个粗略的例子,为简洁起见,它使用了一种自旋锁,而不是基于监视器的适当睡眠。希望它传达了您如何使用标志来控制线程暂停的想法。

请注意,如果您正在块中执行一些长时间运行的步骤集,而不仅仅是setText调用,那么最好Thread.currentThread().interrupted()在每个步骤之间进行检查-

如果设置了itnerrupt标志,则退出循环。广义上讲,这是内置阻塞方法(例如I / O)所做的,以便它们可以被其他线程中断-

由于该running标志仅在每个循环中被检查一次,因此在每个循环中对其进行设置都无济于事需要20分钟。

以上是 如何从另一个线程暂停和恢复Java中的线程 的全部内容, 来源链接: utcz.com/qa/402485.html

回到顶部