Как достучаться до потока?

Рейтинг: 0Ответов: 1Опубликовано: 23.09.2014

Такая проблема: при обращении к потоку t обращается, почему-то, не к t, а к основному потоку (т.е. когда я делаю ob.t.sleep(10000), то засыпает основной поток, что выводит "меню", а не поток, что делает вычисления). Кроме того, когда я пытаюсь использовать wait() (причём, опять же, пытаюсь вызвать через t), то основной поток завершается с выброшенным java.lang.IllegalMonitorStateException, а поток t продолжает работать. Подскажите, что не так? Код:

    import java.util.Scanner;

public class MyThread implements Runnable {
    public static void main (String[] args){
        MyThread ob = new MyThread("Leibnitz");
        int x=-1;
        Scanner in =  new Scanner(System.in);
        while (x != 5){
            System.out.println("1. Продолжить вычисления.\n2. Приостановить вычисления.\n5. Выход.");
            x = in.nextInt();
            switch(x){
            case 1:
                ob.t.notify();
                break;
            case 2:
                try {
                    ob.t.wait();//ob.t.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            }   
        }

    }

private double sum = 0;
protected String name;
protected Thread t;
MyThread(String threadname){
    name = threadname;
    t = new Thread(this,name);
    System.out.println("New thread: " + t);
    t.start();
}

public double getSum() {
    return sum;
}

@Override
public void run() {

    int sign=1; double k=1;
    try{
        while (true) {
        sum = sum + (1/k)*sign;
        k = k+2;
        sign = -sign;
        System.out.println(sum);
        Thread.sleep(2000);
        }
    }catch (InterruptedException e){
        System.out.println("Поток приостановлен.");
    }
}

}

Ответы

▲ 1Принят

Вы не можете заставить поток заснуть из другого потока. Вызов ob.t.sleep не работает потому, что sleep — статической метод и относится лишь к вызывающему его потоку.

А Thread.wait — это на самом деле Object.wait, он тут уж точно ни при чём.

Ваш поток должен сотрудничать. Код, бегущий в потоке, должен по своей инициативе, сам запустить процесс ожидания. Иначе никак.

Если вы хотите, чтобы поток в определённой точке проверил флаг, воспользуйтесь чем-то таким:

static Object sync = new Object();
static boolean stopFlag = false;

// в потоке
synchronized (sync) {
     while (stopFlag)
         sync.wait();
}
// можно продолжать выполнение

// в управляющем потоке
// остановить:
synchronized (sync) {
    stopFlag = true;
}

// запустить:
synchronized (sync) {
    stopFlag = false;
    sync.notify();
}