精华内容
下载资源
问答
  • java 调用exe程序挂起

    2015-07-23 08:34:14
    如果结束java程序的话,挂起的exe会继续执行完。 在网上查了,说在调用完bat文件,等在执行结果waitFor之前处理掉错误流和输出流, 这样做了还不会挂起。 请问大神,问题会出在哪里,怎么解决。。。万分感谢!!!
  • 挂起,终止和恢复线程机制在Java 2和早期版本中有所不同。尽管你运用Java 2的途径编写代码,你仍需了解这些操作在早期Java环境下是如何完成的。例如,你也许需要更新或维护老的代码。你也需要了解为什么Java 2会有.....

    有时,线程的挂起是很有用的。例如,一个独立的线程可以用来显示当日的时间。如果用户不希望用时钟,线程被挂起。在任何情形下,挂起线程是很简单的,一旦挂起,重新启动线程也是一件简单的事。

    挂起,终止和恢复线程机制在Java 2和早期版本中有所不同。尽管你运用Java 2的途径编写代码,你仍需了解这些操作在早期Java环境下是如何完成的。例如,你也许需要更新或维护老的代码。你也需要了解为什么Java 2会有这样的变化。因为这些原因,下面内容描述了执行线程控制的原始方法,接着是Java 2的方法。

    Java 1.1或更早版本的线程的挂起、恢复和终止

    先于Java2的版本,程序用Thread 定义的suspend() 和 resume() 来暂停和再启动线程。它们的形式如下:
        final void suspend( )
        final void resume( )
    下面的程序描述了这些方法:
    // Using suspend() and resume().
    class NewThread implements Runnable {
        String name; // name of thread
        Thread t;
        NewThread(String threadname) {
            name = threadname;
            t = new Thread(this, name);
            System.out.println("New thread: " + t);
            t.start(); // Start the thread
        }
        // This is the entry point for thread.
        public void run() {
            try {
                for(int i = 15; i > 0; i--) {
                    System.out.println(name + ": " + i);
                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                System.out.println(name + " interrupted.");
            }
            System.out.println(name + " exiting.");
        }
    }
    class SuspendResume {
        public static void main(String args[]) {
            NewThread ob1 = new NewThread("One");
            NewThread ob2 = new NewThread("Two");
            try {
                Thread.sleep(1000);
                ob1.t.suspend();
                System.out.println("Suspending thread One");
                Thread.sleep(1000);
                ob1.t.resume();
                System.out.println("Resuming thread One");
                ob2.t.suspend();
                System.out.println("Suspending thread Two");
                Thread.sleep(1000);
                ob2.t.resume();
                System.out.println("Resuming thread Two");
            } catch (InterruptedException e) {
                System.out.println("Main thread Interrupted");
            }
            // wait for threads to finish
            try {
                System.out.println("Waiting for threads to finish.");
                ob1.t.join();
                ob2.t.join();
            } catch (InterruptedException e) {
                System.out.println("Main thread Interrupted");
            }
            System.out.println("Main thread exiting.");
        }
    }
    程序的部分输出如下:
    New thread: Thread[One,5,main]
    One: 15
    New thread: Thread[Two,5,main]
    Two: 15
    One: 14
    Two: 14
    One: 13
    Two: 13
    One: 12
    Two: 12
    One: 11
    Two: 11
    Suspending thread One
    Two: 10
    Two: 9
    Two: 8
    Two: 7
    Two: 6
    Resuming thread One
    Suspending thread Two
    One: 10
    One: 9
    One: 8
    One: 7
    One: 6
    Resuming thread Two
    Waiting for threads to finish.
    Two: 5
    One: 5
    Two: 4
    One: 4
    Two: 3
    One: 3
    Two: 2
    One: 2
    Two: 1
    One: 1
    Two exiting.
    One exiting.
    Main thread exiting.

    Thread类同样定义了stop() 来终止线程。它的形式如下:
        void stop( )
    一旦线程被终止,它不能被resume() 恢复继续运行。

    Java 2中挂起、恢复和终止线程

    Thread定义的suspend(),resume()和stop()方法看起来是管理线程的完美的和方便的方法,它们不能用于新Java版本的程序。下面是其中的原因。Thread类的suspend()方法在Java2中不被赞成,因为suspend()有时会造成严重的系统故障。假定对关键的数据结构的一个线程被锁定的情况,如果该线程在那里挂起,这些锁定的线程并没有放弃对资源的控制。其他的等待这些资源的线程可能死锁。

    Resume()方法同样不被赞同。它不引起问题,但不能离开suspend()方法而独立使用。Thread类的stop()方法同样在Java 2中受到反对。这是因为该方法可能导致严重的系统故障。设想一个线程正在写一个精密的重要的数据结构且仅完成一个零头。如果该线程在此刻终止,则数据结构可能会停留在崩溃状态。

    因为在Java 2中不能使用suspend(),resume()和stop() 方法来控制线程,你也许会想那就没有办法来停止,恢复和结束线程。其实不然。相反,线程必须被设计以使run() 方法定期检查以来判定线程是否应该被挂起,恢复或终止它自己的执行。有代表性的,这由建立一个指示线程状态的标志变量来完成。只要该标志设为“running”,run()方法必须继续让线程执行。如果标志为“suspend”,线程必须暂停。若设为“stop”,线程必须终止。

    当然,编写这样的代码有很多方法,但中心主题对所有的程序应该是相同的。

    下面的例题阐述了从Object继承的wait()和notify()方法怎样控制线程的执行。该例与前面讲过的程序很像。然而,不被赞同的方法都没有用到。让我们思考程序的执行。

    NewTread 类包含了用来控制线程执行的布尔型的实例变量suspendFlag。它被构造函数初始化为false。Run()方法包含一个监测suspendFlag 的同步声明的块。如果变量是true,wait()方法被调用以挂起线程。Mysuspend()方法设置suspendFlag为true。Myresume()方法设置suspendFlag为false并且调用notify()方法来唤起线程。最后,main()方法被修改以调用mysuspend()和myresume()方法。
    // Suspending and resuming a thread for Java2
    class NewThread implements Runnable {
        String name; // name of thread
        Thread t;
        boolean suspendFlag;
        NewThread(String threadname) {
            name = threadname;
            t = new Thread(this, name);
            System.out.println("New thread: " + t);
            suspendFlag = false;
            t.start(); // Start the thread
        }
        // This is the entry point for thread.
        public void run() {
            try {
                for(int i = 15; i > 0; i--) {
                    System.out.println(name + ": " + i);
                    Thread.sleep(200);
                    synchronized(this) {
                        while(suspendFlag) {
                            wait();
                        }
                    }
                }
            } catch (InterruptedException e) {
                System.out.println(name + " interrupted.");
            }
            System.out.println(name + " exiting.");
        }
        void mysuspend() {
            suspendFlag = true;
        }
        synchronized void myresume() {
            suspendFlag = false;
            notify();
        }
    }
    class SuspendResume {
        public static void main(String args[]) {
           NewThread ob1 = new NewThread("One");
           NewThread ob2 = new NewThread("Two");
           try {
              Thread.sleep(1000);
              ob1.mysuspend();
              System.out.println("Suspending thread One");
              Thread.sleep(1000);
              ob1.myresume();
              System.out.println("Resuming thread One");
              ob2.mysuspend();
              System.out.println("Suspending thread Two");
              Thread.sleep(1000);
              ob2.myresume();
              System.out.println("Resuming thread Two");
           } catch (InterruptedException e) {
              System.out.println("Main thread Interrupted");
           }
           // wait for threads to finish
           try {
              System.out.println("Waiting for threads to finish.");
              ob1.t.join();
              ob2.t.join();
           } catch (InterruptedException e) {
               System.out.println("Main thread Interrupted");
           }
           System.out.println("Main thread exiting.");
        }
    }
    该程序的输出与前面的程序相同。此书的后面部分,你将看到用Java 2机制控制线程的更多例子。尽管这种机制不像老方法那样“干净”,然而,它是确保运行时不发生错误的方法。它是所有新的代码必须采用的方法。

     

     Java学习交流群:587131012

    参考资料:http://www.makeru.com.cn/

    展开全文
  • java线程挂起(join)

    2015-03-27 10:10:44
    1、线程挂起join简介 将另外一个线程join到当前线程,则需要等到join进来的线程执行完才会继续执行当前线程。 thread.join();  //当前线程挂起,调用线程 thread,在thread线程执行完毕之前,当前线程一直挂起...

    1、线程挂起join简介

    将另外一个线程join到当前线程,则需要等到join进来的线程执行完才会继续执行当前线程。

    thread.join();      //当前线程挂起,调用线程 thread,在thread线程执行完毕之前,当前线程一直挂起不执行。
    thread.join(1000);  //当前线程挂起,调用线程 thread,等待 thread 线程,等待时间是1000毫秒,超过这个时间,当前线程进入可运行状态。


    2、代码事例

    package com.xxx.util;
    
    import java.util.Date;
    import java.util.concurrent.TimeUnit;
    
    /**
     * Created with IntelliJ IDEA.
     * Date: 15-3-27
     * Time: 上午9:38
     * To change this template use File | Settings | File Templates.
     */
    public class ThreadJoin1 implements  Runnable{
        @Override
        public void run() {
            System.out.printf("Beginning threadJoin1 loading:%s\n",new Date());
            try {
                TimeUnit.SECONDS.sleep(6);
            } catch (InterruptedException e) {
                System.out.println("ThreadJoin1 has bean interrupted");
            }
            System.out.println("ThreadJoin1 loading has finished.");
        }
    }
    
    package com.xxx.util;
    
    import java.util.Date;
    import java.util.concurrent.TimeUnit;
    
    /**
     * Created with IntelliJ IDEA.
     * Date: 15-3-27
     * Time: 上午9:38
     * To change this template use File | Settings | File Templates.
     */
    public class ThreadJoin2 implements  Runnable{
        @Override
        public void run() {
            System.out.printf("Beginning threadJoin2 loading:%s\n",new Date());
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                System.out.println("ThreadJoin2 has bean interrupted");
            }
            System.out.println("ThreadJoin2 loading has finished.");
        }
    }
    
    main类

    package com.xxx.util;
    
    import java.util.Date;
    
    /**
     * Created with IntelliJ IDEA.
     * Date: 15-3-27
     * Time: 上午9:44
     * To change this template use File | Settings | File Templates.
     */
    public class ThreadJoinMain {
        public static void main(String[] args){
            Thread threadJoin1 = new Thread(new ThreadJoin1());
            Thread threadJoin2 = new Thread(new ThreadJoin2());
            threadJoin1.start();
            threadJoin2.start();
            try {
                //main线程等待threadJoin1线程1秒,超过一秒,main线程进入可运行状态
                threadJoin1.join(1000);
                threadJoin2.join();
            } catch (InterruptedException e) {
                System.out.println("Handle InterruptedException.");
            }
            System.out.printf("%s:Configuration has bean loaded:%s\n",Thread.currentThread().getName(),new Date());
        }
    }
    

    3、运行结果


    4、结论

    当前线程挂起等待。



    展开全文
  • 有了进程的自动调度后,接下来的任务在于,如何将空闲进程挂起,空闲进程往往是那些没有具体任务需要处理的进程,因此,如果继续让其运行的话,那么必然会耗费宝贵的CPU资源,如果能让它先挂起,等到它需要执行具体...

    更详细的讲解和代码调试演示过程,请参看视频
    Linux kernel Hacker, 从零构建自己的内核

    有了进程的自动调度后,接下来的任务在于,如何将空闲进程挂起,空闲进程往往是那些没有具体任务需要处理的进程,因此,如果继续让其运行的话,那么必然会耗费宝贵的CPU资源,如果能让它先挂起,等到它需要执行具体任务时,再把它调度到前台,那才是一种合理的进程管理机制。

    我们实现的进程调度,是依赖于进程控制器,也就是taskctl中的任务数组来实现的,当我们想要启动某个进程时,在该数组中找到对应的任务对象,然后把它加载到CPU那就可以了。

    同理,如果要让某个进程休眠,那么只要把它对应的TASK对象从任务数组中移除,那么它自然就不会得到调度的机会。

    因此,修改multi_task.c 增加一个task_sleep函数:

    void task_sleep(struct TASK *task) {
       int  i;
       char ts = 0;
       if (task->flags == 2) {
            if (task == taskctl->tasks[taskctl->now]) {
                ts = 1;
            }
    
        for (i = 0; i < taskctl->running; i++) {
            //在任务数组中找到要挂起的进程对象
            if (taskctl->tasks[i] == task) {
                break;
            }
        }
    
        taskctl->running--;
        if (i < taskctl->now) {
            taskctl->now--;
        }
    
        for(; i < taskctl->running; i++) {
            //通过把后面的任务往前覆盖,实现将当前任务从任务列表中移除的目的
            taskctl->tasks[i] = taskctl->tasks[i+1];
        }
    
        task->flags = 1;
        if (ts != 0) {
            //如果当前挂起的任务正好是当前正在前台运行的任务,那么将第0个任务调度到前台
            if (taskctl->now >= taskctl->running) {
                taskctl->now = 0;
            }
    
           farjmp(0, taskctl->tasks[taskctl->now]->sel);
        }
    
       }
    
       return;
    }
    

    该函数的逻辑是,根据要挂起的任务,在整个任务数组中查找,找到其对应的数组下标,然后把后面的任务向前覆盖,这样的话,要移除的任务就在数组中就会被覆盖掉,从而实现将任务从数组中移除的目的。

    需要注意的是,如果要挂起的任务,正好是当前正在前台运行的进程,那么ts==1,我们就把下标为0的任务调度到前台,并且把任务的数量也就是running的值减一,这样,处于数组最后的那个任务将不会有机会被调度。

    任务挂起是实现了,那么当我们想重新把任务调度到前台时,该怎么做呢?我们可以利用现有的队列机制,回忆一下,一旦鼠标,键盘的事件发生时,我们会把硬件产生的数据加入到他们对应的队列中,然后在CMain主循环中,将队列中的数据取出来处理。同理,当我们挂起一个任务时,我们把挂起的任务对象放入到一个队列中,当想要重新调度这个对象时,我们往队列里发送一个数据,然后在主循环中对该队列进行检查,一旦发现队列中含有数据的话,那么就把队列中寄存的任务重新加入调度数组。代码修改如下,在golbal_define.c中:

    void fifo8_init(struct FIFO8 *fifo, int size, unsigned char *buf, 
        struct TASK *task) {
        fifo->size = size;
        fifo->buf = buf;
        fifo->free = size;
        fifo->flags = 0;
        fifo->p = 0;
        fifo->q = 0;
        fifo->task = task;
        return ;
    }

    在初始化一个队列时,把一个任务对象添加进去,如果队列不需要寄存任务对象,那么把task设置为0就可以。

    int fifo8_put(struct FIFO8 *fifo, unsigned char data) {
        if (fifo == 0) {
            return -1;
        }    
    
        if (fifo->free ==0) {
            fifo->flags |= FLAGS_OVERRUN;
            return -1;
        }
    
        fifo->buf[fifo->p] = data;
        fifo->p++;
        if (fifo->p == fifo->size) {
            fifo->p = 0;
        }
    
        fifo->free--;
    
        if (fifo->task != 0) {
            if (fifo->task->flags != 2) {
                task_run(fifo->task);
            }
        }
    
        return 0;
    }

    当队列中有数据加入时,顺便查看该队列是否寄存着一个任务对象,如果是,那么把该任务对象加入调度数组。

    由于timer.c中,对计时器的运行需要使用到队列,既然队列的数据结构有变动,因此timer.c中,需要做一点小改动:

    static struct TIMERCTL timerctl;
    extern struct TIMER *task_timer;
    
    void  init_pit(void) {
        io_out8(PIT_CTRL, 0x34);
        io_out8(PIT_CNT0, 0x9c);
        io_out8(PIT_CNT0, 0x2e);
    
        timerctl.count = 0;
        int i;
        for (i = 0; i < MAX_TIMER; i++) {
            timerctl.timer[i].flags = 0; //not used
            timerctl.timer[i].fifo = 0;
        }
    }

    上面的改动在于,把每个timer对象的fifo队列成员设置为0。

    接下来的改动主要在主入口函数中:

    void CMain(void) {
        ....
        fifo8_init(&timerinfo, 8, timerbuf, 0);
        ....
        fifo8_init(&keyinfo, 32, keybuf, 0);
        ....
        task_a = task_init(memman);
        keyinfo.task = task_a;
        ....
    }

    上面代码的逻辑是,先通过task_init得到CMain函数所对应的任务对象,并把该任务对象寄存在键盘事件列表中,也就是keyinfo.task = task_a;

    void CMain(void) {
        ....
        task_run(task_b);
        ...
        int pos = 0;
        int stop_task_A = 0;
         for(;;) {
    
           io_cli();
           ....
           else if (fifo8_status(&timerinfo) != 0) {
               io_sti();
               int i = fifo8_get(&timerinfo);
               if (i == 10) {
                    showString(shtctl, sht_back, pos, 144, COL8_FFFFFF,
                     "A"); 
    
                    timer_settime(timer, 100);
                    pos += 8;
                    if (pos > 40 && stop_task_A == 0) {
                        io_cli();
                        task_sleep(task_a);
                        io_sti();
                     }
               }
           ....
        }
    }

    上面代码的逻辑时,当CMain函数在主循环中,连续打印字符”A”,当打印的字符超过5个时,通过task_sleep(task_a)把CMain进程挂起。这样的话,系统运行时,我们会发现原来是字符A和B 是同时打印到桌面上的,此时便只剩下字符B在继续打印了。

    这里写图片描述

    由于我们把task_A寄存到键盘队列,那么当我们点击键盘,于是键盘数据就会存储到键盘队列中,由于键盘队列存储了任务Ad的任务对象,那么此时他会把对应任务对象重新加入到调度队列中,由此字符A会从恢复打印状态,也就是说,打印字符A的进程重新获得了被调度的机会。

    这里写图片描述

    参看视频,可以获得更加生动的演示展示。

    更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:
    这里写图片描述

    展开全文
  • Java线程的挂起与唤醒

    千次阅读 2013-08-17 14:11:15
    private Thread mythread; public void start() {  if (mythread==null){ mythread=new Thread(); mythread.start(); } else {  mythread.resume(); } } public void run() ...try{

    private Thread mythread;

    public void start()

    if (mythread==null){

    mythread=new Thread();

    mythread.start();

    }

    else { 

    mythread.resume();

    }

    }
    public void run()

    {  

    while(true) {   

    try{

    sleep(100);

            catch(InterruptedException e) {}

    }

    }
    public void stop()

    {

    mythread.suspend();

    }

    展开全文
  • Linux 后台执行 java 进程不挂起

    千次阅读 2014-11-22 21:46:33
    nohup java -jar domain.jar &
  • java runtime exec 运行挂起的问题

    千次阅读 2011-11-24 10:51:10
    这两天让一个同事去做一个ORACLE数据定时备份的工作,结果她写完代码后发现可以导出备份文件,但是使用RUNTIME的时候没办法结束,也就是说这个进程一直处于挂起的状态,是什么原因呢? 为了解决这个问题到网上找了...
  • (java)关于Thread的挂起和恢复

    千次阅读 2010-03-26 01:06:00
    今天在做 Thread的测试,主要目的就是了解下线程的挂起和恢复。 差了很多资料,一直用的是wait()和notify()函数,结果总是出错,后来又找... //挂起线程 java之所以取消这两个函数,是因为容易照成死锁,但是对于很
  • java调用外部程序挂起原因

    千次阅读 2009-05-06 10:12:00
    当执行的外部命令没有任何输出的时候,这段代码运行正常,但如果执行的外部命令有输出的时候,这段程序就会挂起,估计是因为流没有被读取导致了堵塞,于是把代码改为 public   void  test()  ...
  • 今天在练习soket编程的时候遇到这么个问题,每次程序运行到上面代码第5行时就会挂起。  后来把代码改成这样 byte[] bytes = new byte[64]; //读取输入流数据 int readLen = 0; while((readLen = ...
  • java中Timer因修改系统时间致使任务被挂起的原因private void mainLoop() { while (true) { try { TimerTask task; boolean taskFired; synchronized(queue) {
  • JAVA线程之三:线程的挂起和恢复

    万次阅读 2010-04-20 13:43:00
    (1)概述:线程的挂起操作实质上就是使线程进入“非可执行”状态下,在这个状态下CPU不会分给线程时间片,进入这个状态可以用来暂停一个线程的运行。在线程挂起后,可以通过重新唤醒线程来使之恢复运行。  run() ...
  • 挂起和恢复线程  Thread 的API中包含两个被淘汰的方法,它们用于临时挂起和重启某个线程,这些方法已经被淘汰,因为它们是不安全的,不稳定的。如果在不合适的时候挂起线程(比如,锁定共享资源时),此时便可能...
  • 一, 什么是线程的挂起与恢复 从字面理解也很简单. 所谓线程挂起就是指暂停线程的执行(阻塞状态). 而恢复时就是让暂停的线程得以继续执行.(返回就绪状态) 二, 为何需要挂起和恢复线程. 我们来看1个经典的例子...
  • 现在的Java EE 系统通常都依赖于远程服务,需要通过网络请求获取远程服务。不管是使用什么协议(HTTP,HTTPS,JDBC 等)请求远程服务,Java VM最终都将委托给Socket去实现。首先会通过connect方法与远程服务建立连接...
  • 如果在不合适的时候挂起线程(比如,锁定共享资源时),此时便可能会发生死锁条件,另外,在长时间计算期间挂起线程也可能导致问题。  下面的代码演示了通过休眠来延缓运行,模拟长时间运行的情况,使线程更可能在...
  • at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) at java.util.concurrent.FutureTask.setException(FutureTask.java:125) at java.util.concurrent.FutureTask$Sync....
  • 挂起和恢复线程  Thread 的API中包含两个被淘汰的方法,它们用于临时挂起和重启某个线程,这些方法已经被淘汰,因为它们是不安全的,不稳定的。如果在不合适的时候挂起线程(比如,锁定共享资源时),此时便可能...
  • 这两天在研究多线程的使用方法,我们的需求是这样的:程序启动时,先让子线程处于运行状态,运行过程中会人为的更改该线程的运行状态为挂起,等待随机的时长之后,再把该线程重新唤醒,让其继续运行;人为挂起线程和...
  • 创建一个进程后,如果进程产生大量的输出而不去读取的话,当超出系统的缓存时,此进程会被挂起,而正在运行的程序又因proc.waitFor();在等待进程的消亡,所以产生了一个死锁。   从网上找到了一个解决...
  • Java socket编程时,常使用BufferedReader的...但是该函数是阻塞的,如果在接收的数据中不含有'\n','\r'或者结束符时,往往导致进程挂起,从而程序无法继续。 所以在发送数据的另一端,一定要记得在最后加换行符。
  • 最近写Java的多进程程序时遇到一个奇怪的问题,发现程序运行一段时间以后会自动挂起。按道理来说子进程和父进程之间是没有太大的关系的,父进程只是用于开启一个新的子进程,之后就没怎么联系了。最后查到了...
  • 挂起:一般是主动的,由系统或程序发出,甚至于辅存中去。(不释放CPU,可能释放内存,放在外存) 阻塞:一般是被动的,在抢占资源中得不到资源,被动的挂起在内存,等待某种资源或信号量(即有了资源)将他唤  ...
  • 挂起和恢复线程  Thread 的API中包含两个被淘汰的方法,它们用于临时挂起和重启某个线程,这些方法已经被淘汰,因为它们是不安全的,不稳定的。如果在不合适的时候挂起线程(比如,锁定共享资源时),此时便可能...
  • 当command的输出内容过大时(OS的I/O buffer容纳不下输出流时),程序会被挂起。解决此内问题的方法将command的输出流proc.getErrorStream(),proc.getInputStream()清空。以下为一示例, linux7.2,jdk1.5.0_0
  • 源码如下:  在客户端运行正常,但在服务器端...import java.io.InputStreamReader; import java.io.LineNumberReader; import lotus.domino.AgentBase; import lotus.domino.Database; import lotus.domino.S
  • 利用serverSocket给的借口关闭正在挂起的accept方法总不是太有效,但是开启serverSocket知道自己什么时候需要关闭,在关闭前如果利用一个无用的Socket将accept状态解除,那么就能成功的关闭处在在accept中的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 139,829
精华内容 55,931
关键字:

java挂起

java 订阅