Обработка сигналов Java, а затем возврат к основной программе

У MI есть программа, которая начинается с цикла for и вращается 10 раз, а один цикл длится одну секунду. Мне нужно обработать сигнал (CTRL+C), и при обработке он должен выполнить свой собственный цикл for, а после его остановки я должен вернуться к основному циклу. Мне удалось сделать почти все вышеперечисленное, но циклы не выполняются отдельно. Делают это параллельно. Надеюсь, вы можете помочь... спасибо :)

Кстати, мой код:

import sun.misc.Signal;
import sun.misc.SignalHandler;

public class MySig {

    public static void shhh(int s){ //s -> seconds :)
        s = s*1000;
        try{
            Thread.sleep(s);
        }catch(InterruptedException e){
            System.out.println("Uh-oh :(");
        }
    }

  public static void main(String[] args){
      Signal.handle(new Signal("INT"), new SignalHandler () {
      public void handle(Signal sig) {
      for(int i=0; i<5; i++){
        System.out.println("+");
        shhh(1);
    }
    }
    });
    for(int i=0; i<10; i++) {
      shhh(1);
      System.out.println(i+"/10");
    }
  } 
}

person dmacan23    schedule 20.03.2013    source источник
comment
Я действительно не понимаю ни вашего вопроса, ни того, что должен делать ваш код?   -  person Smit    schedule 21.03.2013
comment
Это домашняя работа в колледже... Моя программа должна обрабатывать сигнал, который приходит, когда я нажимаю CTRL+C во время работы цикла, запускаю другой цикл для этого сигнала, и после обработки всех сигналов просто возвращаюсь к основной цикл и продолжить... Извините, если я недостаточно ясно выразился   -  person dmacan23    schedule 21.03.2013


Ответы (1)


Правильно, согласно документам, SignalHandler выполняется в отдельном потоке:

... когда виртуальная машина получает сигнал, специальный обработчик сигналов C создает новый поток (с приоритетом Thread.MAX_PRIORITY) для запуска зарегистрированного обработчика сигналов Java.

Если вы хотите остановить свой основной цикл во время выполнения обработчика, вы можете добавить механизм блокировки, что-то вроде этого:

private static final ReentrantLock lock = new ReentrantLock(true);
private static AtomicInteger signalCount = new AtomicInteger(0);

public static void shhh(int s) { // s -> seconds :)
    s = s * 1000;
    try {
        System.out.println(Thread.currentThread().getName() + " sleeping for "
                + s + "s...");
        Thread.sleep(s);
    } catch (InterruptedException e) {
        System.out.println("Uh-oh :(");
    }
}

public static void main(String[] args) throws Exception {
    Signal.handle(new Signal("INT"), new SignalHandler() {
        public void handle(Signal sig) {
            // increment the signal counter
            signalCount.incrementAndGet();
            // Acquire lock and do all work
            lock.lock();
            try {
                for (int i = 0; i < 5; i++) {
                    System.out.println("+");
                    shhh(1);
                }
            } finally {
                // decrement signal counter and unlock
                signalCount.decrementAndGet();
                lock.unlock();
            }
        }

    });
    int i = 0;
    while (i < 10) {
        try {
            lock.lock();
            // go back to wait mode if signals have arrived
            if (signalCount.get() > 0)
                continue;
            System.out.println(i + "/10");
            shhh(1);
            i++;
        } finally {
            // release lock after each unit of work to allow handler to jump in
            lock.unlock();
        }
    }
}

Может быть лучшая стратегия блокировки.

person Blake    schedule 21.03.2013
comment
Это здорово, но затем, если я нажму CTRL+C уже при обработке одного сигнала, он обрабатывает первый сигнал до конца, проходит один раз через основной цикл, а затем обрабатывает второй сигнал... Я бы хотел, чтобы он начинает обрабатывать второй сигнал, как только я его отправляю, затем обрабатывает предыдущий и так далее, пока не будут обработаны все сигналы, а затем возвращается к основному циклу... Я знаю, я забыл упомянуть об этом выше.. . простите - person dmacan23; 21.03.2013
comment
Я отредактировал приведенный выше код для достижения этой цели, хотя он определенно не выглядит элегантным. По сути, я только что ввел новый счетчик сигналов, и основной поток проверяет этот счетчик и возвращается в режим ожидания, если счетчик > 0 - person Blake; 22.03.2013