精华内容
下载资源
问答
  • i have created a wizard programatically. it contain 3 panels. the second one is devicePane and third one is detailsPane. the third panel consist of a progress bar. i want my program to start a functio...

    i have created a wizard programatically. it contain 3 panels. the second one is devicePane and third one is detailsPane. the third panel consist of a progress bar. i want my program to start a function process() after displaying the third panel? is it possible using thread?

    else if(ParserMainDlg.this.POSITION==1){

    if(sqlConnectionPane.executeProcess()==true){

    devicePane.setDeviceList();

    ParserMainDlg.this.POSITION++;

    fireStateChanged(oldValue);

    }

    }

    else if(ParserMainDlg.this.POSITION==2){

    System.out.println("position:"+ParserMainDlg.this.POSITION);

    if(devicePane.executeProcess()==true){

    ParserMainDlg.this.POSITION++;

    fireStateChanged(oldValue);

    }

    I want sqlConnectionPane.executeProcess() to call a function which starts executing after displaying the devicePane Panel?

    解决方案

    You can definitly use a thread to execute your task, this is the preferred way of handling a long running task.

    You have multiple options here. All options include making a callback to your wizard, to update the progressbar.

    You can make your own task class wich does exactly this, or you can use the existing SwingWorker. "SwingWorker itself is an abstract class; you must define a subclass in order to create a SwingWorker object; anonymous inner classes are often useful for creating very simple SwingWorker objects."

    Using the swing worker we just learned about you can use something like this:

    SwingWorker backgroundWork = new SwingWorker() {

    @Override

    protected final Integer doInBackground() throws Exception {

    for (int i = 0; i < 61; i++) {

    Thread.sleep(1000);

    this.publish(i);

    }

    return 60;

    }

    @Override

    protected final void process(final List chunks) {

    progressBar.setValue(chunks.get(0));

    }

    };

    backgroundWork.execute();

    Note that you will have to break your task down into smaller parts to actually be able to display progress.

    展开全文
  • 挂起和恢复线程Thread 的API中包含两个被淘汰的方法,它们用于临时挂起和重启某个线程,这些方法已经被淘汰,因为它们是不安全的,不稳定的。如果在不合适的时候挂起线程(比如,锁定共享资源时),此时便可能会发生...

    挂起和恢复线程

    Thread 的API中包含两个被淘汰的方法,它们用于临时挂起和重启某个线程,这些方法已经被淘汰,因为它们是不安全的,不稳定的。如果在不合适的时候挂起线程(比如,锁定共享资源时),此时便可能会发生死锁条件——其他线程在等待该线程释放锁,但该线程却被挂起了,便会发生死锁。另外,在长时间计算期间挂起线程也可能导致问题。

    下面的代码演示了通过休眠来延缓运行,模拟长时间运行的情况,使线程更可能在不适当的时候被挂起:

    public class DeprecatedSuspendResume extends Object implements Runnable{

    //volatile关键字,表示该变量可能在被一个线程使用的同时,被另一个线程修改

    private volatile int firstVal;

    private volatile int secondVal;

    //判断二者是否相等

    public boolean areValuesEqual(){

    return ( firstVal == secondVal);

    }

    public void run() {

    try{

    firstVal = 0;

    secondVal = 0;

    workMethod();

    }catch(InterruptedException x){

    System.out.println("interrupted while in workMethod()");

    }

    }

    private void workMethod() throws InterruptedException {

    int val = 1;

    while (true){

    stepOne(val);

    stepTwo(val);

    val++;

    Thread.sleep(200);  //再次循环钱休眠200毫秒

    }

    }

    //赋值后,休眠300毫秒,从而使线程有机会在stepOne操作和stepTwo操作之间被挂起

    private void stepOne(int newVal) throws InterruptedException{

    firstVal = newVal;

    Thread.sleep(300);  //模拟长时间运行的情况

    }

    private void stepTwo(int newVal){

    secondVal = newVal;

    }

    public static void main(String[] args){

    DeprecatedSuspendResume dsr = new DeprecatedSuspendResume();

    Thread t = new Thread(dsr);

    t.start();

    //休眠1秒,让其他线程有机会获得执行

    try {

    Thread.sleep(1000);}

    catch(InterruptedException x){}

    for (int i = 0; i 

    //挂起线程

    t.suspend();

    System.out.println("dsr.areValuesEqual()=" + dsr.areValuesEqual());

    //恢复线程

    t.resume();

    try{

    //线程随机休眠0~2秒

    Thread.sleep((long)(Math.random()*2000.0));

    }catch(InterruptedException x){

    //略

    }

    }

    System.exit(0); //中断应用程序

    }

    }

    某次运行结果如下:

    2b2862dcff5a9e4d109c143410f82d5d.png

    从areValuesEqual()返回的值有时为true,有时为false。以上代码中,在设置firstVal之后,但在设置secondVal之前,挂起新线程会产生麻烦,此时输出的结果会为false(情况1),这段时间不适宜挂起线程,但因为线程不能控制何时调用它的suspend方法,所以这种情况是不可避免的。

    当然,即使线程不被挂起(注释掉挂起和恢复线程的两行代码),如果在main线程中执行asr.areValuesEqual()进行比较时,恰逢stepOne操作执行完,而stepTwo操作还没执行,那么得到的结果同样可能是false(情况2)。

    下面我们给出不用上述两个方法来实现线程挂起和恢复的策略——设置标志位。通过该方法实现线程的挂起和恢复有一个很好的地方,就是可以在线程的指定位置实现线程的挂起和恢复,而不用担心其不确定性。

    对于上述代码的改进代码如下:

    public class AlternateSuspendResume extends Object implements Runnable {

    private volatile int firstVal;

    private volatile int secondVal;

    //增加标志位,用来实现线程的挂起和恢复

    private volatile boolean suspended;

    public boolean areValuesEqual() {

    return ( firstVal == secondVal );

    }

    public void run() {

    try {

    suspended = false;

    firstVal = 0;

    secondVal = 0;

    workMethod();

    } catch ( InterruptedException x ) {

    System.out.println("interrupted while in workMethod()");

    }

    }

    private void workMethod() throws InterruptedException {

    int val = 1;

    while ( true ) {

    //仅当贤臣挂起时,才运行这行代码

    waitWhileSuspended();

    stepOne(val);

    stepTwo(val);

    val++;

    //仅当线程挂起时,才运行这行代码

    waitWhileSuspended();

    Thread.sleep(200);

    }

    }

    private void stepOne(int newVal)

    throws InterruptedException {

    firstVal = newVal;

    Thread.sleep(300);

    }

    private void stepTwo(int newVal) {

    secondVal = newVal;

    }

    public void suspendRequest() {

    suspended = true;

    }

    public void resumeRequest() {

    suspended = false;

    }

    private void waitWhileSuspended()

    throws InterruptedException {

    //这是一个“繁忙等待”技术的示例。

    //它是非等待条件改变的最佳途径,因为它会不断请求处理器周期地执行检查,

    //更佳的技术是:使用Java的内置“通知-等待”机制

    while ( suspended ) {

    Thread.sleep(200);

    }

    }

    public static void main(String[] args) {

    AlternateSuspendResume asr =

    new AlternateSuspendResume();

    Thread t = new Thread(asr);

    t.start();

    //休眠1秒,让其他线程有机会获得执行

    try { Thread.sleep(1000); }

    catch ( InterruptedException x ) { }

    for ( int i = 0; i 

    asr.suspendRequest();

    //让线程有机会注意到挂起请求

    //注意:这里休眠时间一定要大于

    //stepOne操作对firstVal赋值后的休眠时间,即300ms,

    //目的是为了防止在执行asr.areValuesEqual()进行比较时,

    //恰逢stepOne操作执行完,而stepTwo操作还没执行

    try { Thread.sleep(350); }

    catch ( InterruptedException x ) { }

    System.out.println("dsr.areValuesEqual()=" +

    asr.areValuesEqual());

    asr.resumeRequest();

    try {

    //线程随机休眠0~2秒

    Thread.sleep(

    ( long ) (Math.random() * 2000.0) );

    } catch ( InterruptedException x ) {

    //略

    }

    }

    System.exit(0); //退出应用程序

    }

    }

    运行结果如下:

    bd5c66c15219d314b3491a282596209a.png

    线程挂起的位置不确定main线程中执行asr.areValuesEqual()进行比较时,恰逢stepOne操作执行完,而stepTwo操作还没执行)asr.areValuesEqual()操作前,让main线程休眠450ms(>300ms),如果挂起请求发出时,新线程正执行到或即将执行到stepOne操作(如果在其前面的话,就会响应挂起请求,从而挂起线程),那么在stepTwo操作执行前,main线程的休眠还没结束,从而main线程休眠结束后执行asr.areValuesEqual()操作进行比较时,stepTwo操作已经执行完,因此也不会出现输出结果为false的情况。

    可以将ars.suspendRequest()代码后的sleep代码去掉,或将休眠时间改为200(明显小于300即可)后,查看执行结果,会发现结果中依然会有出现false的情况。如下图所示:

    d2e9bfb23f45407b83d6a026a3981723.png

    总结:线程的挂起和恢复实现的正确方法是:通过设置标志位,让线程在安全的位置挂起

    终止线程

    当调用Thread的start()方法,执行完run()方法后,或在run()方法中return,线程便会自然消亡。另外Thread

    API中包含了一个stop()方法,可以突然终止线程。但它在JDK1.2后便被淘汰了,因为它可能导致数据对象的崩溃。一个问题是,当线程终止时,很少有机会执行清理工作;另一个问题是,当在某个线程上调用stop()方法时,线程释放它当前持有的所有锁,持有这些锁必定有某种合适的理由——也许是阻止其他线程访问尚未处于一致性状态的数据,突然释放锁可能使某些对象中的数据处于不一致状态,而且不会出现数据可能崩溃的任何警告。

    终止线程的替代方法:同样是使用标志位,通过控制标志位来终止线程。

    展开全文
  • 参考:写了个demo:#include #include static pthread_mutex_t mutex;static pthread_cond_t cond;static int flag = 0;void srpthread_init(){pthread_mutex_init(&mutex,NULL);pthread_cond_init(&...

    参考:

    写了个demo:

    #include

    #include

    static pthread_mutex_t mutex;

    static pthread_cond_t cond;

    static int flag = 0;

    void srpthread_init()

    {

    pthread_mutex_init(&mutex,NULL);

    pthread_cond_init(&cond,NULL);

    }

    void srpthread_suspend()

    {

    pthread_mutex_lock(&mutex);

    flag--;

    pthread_mutex_unlock(&mutex);

    }

    void srpthread_resume()

    {

    pthread_mutex_lock(&mutex);

    flag++;

    pthread_cond_signal(&cond);

    pthread_mutex_unlock(&mutex);

    }

    void *thread_run()

    {

    while(1)

    {

    pthread_mutex_lock(&mutex);

    while(flag<=0)

    {

    pthread_cond_wait(&cond,&mutex);

    }

    pthread_mutex_unlock(&mutex);

    //actual work

    printf("i am running!\n");

    }

    }

    int main(int argc,char *argv[])

    {

    char ch;

    pthread_t p1;

    srpthread_init();

    pthread_create(&p1,NULL,(void *)thread_run,NULL);

    while(1)

    {

    scanf("%c",&ch);

    switch(ch)

    {

    case 's':

    srpthread_suspend();

    break;

    case 'r':

    srpthread_resume();

    break;

    default:

    break;

    }

    }

    #if 0

    printf("1111\n");

    srpthread_resume();

    printf("2222\n");

    sleep(3);

    printf("3333\n");

    srpthread_suspend();

    printf("4444\n");

    #endif

    return 1;

    }

    编译命令: gcc file.c -o file lpthread

    展开全文
  • 一文读懂 线程 挂起

    2020-12-31 15:49:52
    要想理解线程挂起,我们得先明白线程是如何被执行的,当程序运行之后,系统会创建一个进程,进程是一个资源单位,代表程序可以使用的资源,而线程才是真正的执行单位,参与操作系统的调度 每个线程都有一个 task_...

    做为一个码农,在开发的时候,经常会使用到  Object.wait 等操作,挂起当前线程,当时我心里一直有个疑惑,这个挂起底层到底是如何实现的呢?

    要想理解线程挂起,我们得先明白线程是如何被执行的,当程序运行之后,系统会创建一个进程,进程是一个资源单位,代表程序可以使用的资源,而线程才是真正的执行单位,参与操作系统的调度

    每个线程都有一个 task_struct 结构体(简称PCB),当然也可以理解为一个对象,这个结构体会被操作系统添加到一个队列中(简称 调度队列 ),这个结构体如下

    操作系统给每一个线程PCB中参数赋值, self_kstack 保存了我们的编写的运行函数地址,表示cpu要执行那个函数, ticks 代表这个线程可以使用多少cpu时间,比如 ticks  = 5 ... 等,  那么操作系统是如何知道线程使用了多少CPU时间呢 ?

    这里会涉及一些中断的知识,我们只是想了解线程是如何被执行,被挂起的,所以这里就不细讲中断是什么了,暂时先可以理解为是一个操作系统的函数(简称 调度函数)。

    假设每隔10ms,cpu就切换到这个调度函数,调用前操作系统会替我们保护好当前线程执行的代码位置等一些参数到 self_kstack,然后在调度函数中,取出当前正在执行的线程,把该线程PCB中的 ticks 减 1 , 然后通过 self_kstack 还原线程参数和执行代码位置,继续执行。

    如果减1之后,该线程的 ticks 等于 0 ,那么操作系统会从 调度队列头部 取出一个新PCB,然后去执行这个PCB中 self_kstack 指向的函数地址和代码位置,然后把当前线程的PCB放到队列尾部(注意,此时当前线程的PCB中还记录着当前的代码位置...等一些参数)。

    就这样,每隔50ms就切换一个线程不间断的轮流执行,就实现了简单的任务调度

    那么,线程挂起又是怎样的实现的呢? 其实很简单,我们知道想要线程执行,必须把线程的PCB放入调度队列,才有机会被cpu调度。如果我们不把当前线程的PCB放到调度队列,那么这个线程就永远不会被执行,不就是被挂起了吗? 有的同学可能会问,线程没在调度队列里,那么如果想唤醒这个线程的话,该怎么办?

    这也是我们使用 Object.wait / Object.notify 的时候,为什么必须要加锁的原因,一个锁结构有下列字段

    value字段,代表这个锁是否被别人持有,等于1的话代表空闲,waiters 是一个等待队列,存放线程的PCB。

    我们在一个加锁的代码块里执行 Object.wait 的时候,操作系统会把当前线程的PCB从调度队列中移除,然后放入当前锁的等待队列中,所以当前线程被挂起。

    显而易见,当在一个加锁的代码块里执行Object.notify的时候,操作系统从当前锁的等待队列中,取出一个PCB,加入到调度队列的首部,这样当前线程会很快的被cpu调度,所以线程被唤醒

    通过添加/移除调度队列中的PCB,实现线程的挂起和唤醒,是不是很容易理解呢?

    展开全文
  • PYQT5 线程挂起方法

    2021-01-21 22:32:13
    QThread线程挂起需要一个QWaitCondition对象,并且需要传入一个QMutex对象作为参数,QMutex对象初始化的时候应该是锁定状态,否则将出现异常情况,参考 QT多线程QWaitCondition的问题 ... 然后再调用cond.wait()挂起...
  • 线程从创建、运行到结束总是处于下面五个状态之一:新建状态、就绪状态、运行状态、阻塞状态及死亡状态。...操作系统中睡眠、阻塞、挂起的区别形象解释:首先这些术语都是对于线程来说的。对线程的控制就好比你
  • Java线程挂起

    2021-07-17 01:26:39
    I'm creating a Java Slideshow using some 2DTransitions I found on the net. Everything work smoothly, but I come across a problem why trying to execute code after the Slideshow has been rendered....
  • 通过Javacore了解线程运行情况: Javacore,也可以称为“threaddump”或是“javadump”,它是 Java 提供的一种诊断特性,能够提供一份可读的当前运行的 JVM 中线程使用情况的快照。即在某个特定时刻,JVM 中有哪些...
  • Java 实例 - 线程挂起

    2021-03-21 10:23:07
    以下实例演示了如何将线程挂起:/*author by w3cschool.ccSleepingThread.java*/public class SleepingThread extends Thread {private int countDown = 5;private static int threadCount = 0;public ...
  • Java 实例 – 线程挂起

    2021-02-28 15:06:53
    Java 实例 - 线程挂起以下实例演示了如何将线程挂起:/*author by w3cschool.cnSleepingThread.java*/public class SleepingThread extends Thread {private int countDown = 5;private static int threadCount = 0;...
  • 常见由线程挂起导致的现象程序处理速度由慢到严重超时,最后全部超时,重启程序会循环这一现象,那90%是线程被挂起了。常见的线程挂起或死锁有线程锁里面出现死循环,锁不能被释放,导致其它线程一直等待;锁里加锁...
  • POSIX的Linux操作系统没有提供线程挂起和恢复的例程,在网上找了找,看到一个老外写的程序,感觉想法不错,放在这里大家分享一下。理论上应该可以实现,不过我没有试,给大家提供一个参考。void CPrcThread::suspend...
  • Java线程挂起、恢复和终止下一节>有时,线程挂起是很有用的。例如,一个独立的线程可以用来显示当日的时间。如果用户不希望用时钟,线程挂起。在任何情形下,挂起线程是很简单的,一旦挂起,重新启动线程也...
  • 请注意:我正在使用JClouds标记这一点,因为如果您阅读了整个问题...我使用VisualVM(关注正在运行的线程)对其进行了分析,并且我还在一个日志语句中进行了打印,以便在应用程序挂起的位置(在main()方法的末尾)进行打印...
  • [15-1-30 16:32:17:797 CST] 00000003ThreadMonitor W WSVR0605W: 线程“WebContainer :26”(0000029f)已保持活动状态 685090 毫秒,此线程可能已挂起。在服务器中共有 25个线程可能处于挂起状态。at sun.misc....
  • 一,介绍本文讨论JAVA多线程中,使用 thread.suspend()方法暂停线程,使用 thread.resume()恢复暂停的线程 的特点。先介绍二个关于线程的基本知识:①线程的执行体是run()方法里面的每一条语句,main线程执行的则是...
  • 前几篇都介绍了几个关于Thread的几个方法,下面就来总结一下吧,首先来看一张图,下面这张图很清晰的说明了线程的状态与Thread中的各个方法之间的关系,很经典的!在Java中创建线程有两种方法:使用Thread类和使用...
  • 一,介绍本文讨论Java多线程中,使用 thread.suspend()方法暂停线程,使用 thread.resume()恢复暂停的线程的特点。先介绍二个关于线程的基本知识:①线程的执行体是run()方法里面的每一条语句,main线程执行的则是...
  • java中,线程的状态使用一个枚举类型来描述的。...但是我发现大多数人的理解和上面的这六种还是有些差别,通常会加上阻塞状态,可运行状态,挂起状态。这是Thread类描述线程状态的枚举类的源代码:public enu...
  • packagecom.wenjie;public class AlternateSuspendResume extends Object implementsRunnable {private volatile intfirstVal;...//增加标志位,用来实现线程挂起和恢复private volatile booleansuspende...
  • 挂起和恢复线程​ Thread 的API中包含两个被淘汰的方法,它们用于临时挂起和重启某个线程,这些方法已经被淘汰,因为它们是不安全的,不稳定的。如果在不合适的时候挂起线程(比如,锁定共享资源时),此时便可能会...
  • osThreadSuspend可以让线程A挂起线程A保持在BLOCKED状态,直到其他线程使用osThreadResume唤起线程A。如果其他线程的优先级低于线程A,那么唤起的瞬间就会上下文切换至线程A,就是说线程A马上运行。 STM32工程: ...
  • 暂停线程意味着此线程还可以恢复运行。在 Java 多线程中,可以使用 suspend() 方法暂停线程,使用 resume() 方法恢复线程的执行。suspend() 与 resume() 方法本节通过一个案例来介绍 suspend() 与 resume() 方法的...
  • I searched and found ways to determine if another thread is suspended by adding a boolean to it. But, I do not want (prefer not) to modify that other thread's code. And, I need to detect if it is froz...
  • 故自己整理了一下程序流程为:主线程创建子线程(当前子线程状态为stop停止状态),5秒后主线程唤醒子线程,10秒后主线程挂起子线程,15秒后主线程再次唤醒子线程,20秒后主线程执行完毕等待子...
  • 使用start和join代替run:import multiprocessing, sys, timedef f(icount, _sleepTime = 1):for i in range(icount):time.sleep(_sleepTime)print(_sleepTime)def main(args):m = multiprocessing.Process(target =...
  • 1.1 中断方法在独占锁加锁过程中,我们看到,线程进入sync queue中后便调用park()方法将自己挂起。等待其他线程调用unpark()方法唤醒自己。那么当我们调用interrupt()方法时,是否可以中断被操作系统挂起线程呢?...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 209,212
精华内容 83,684
关键字:

线程挂起