Страницы

Поиск по вопросам

вторник, 31 декабря 2019 г.

В чем разница в создании потоков используя Thread и Runnable?

#java #многопоточность


А если быть конкретнее - интересует вот что.
Допустим у нас есть код, вот такой:

public class Main{  
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        Thread t1 = new Thread(myThread);
        t1.start();
        myThread.sysOut();  
    }
}

public class MyThread implements Runnable {
    public void run(){
    }

    public void sysOut(){
        System.out.println("Banana!");
    }
}


Правильно ли я понимаю, что вызывая myThread.sysOut() этот метод будет вызываться
в основном потоке, а не в потоке t1 ?
Если же я понимаю правильно, каким образом извне вызвать метод sysOut не в основном
потоке имплементируя интерфейс Runnable, а не наследуясь от класса Thread ?
    


Ответы

Ответ 1



Нельзя прямо вот так взять и вызвать метод в другом потоке. Можно каким-то образом послать в поток условный сигнал, по которому он поймёт что от него требуется и сделает это. public class Main{ public static void main(String[] args) { MyThread myThread = new MyThread(); Thread t1 = new Thread(myThread); t1.start(); myThread.sysOutInThread(); } } public class MyThread implements Runnable { public void run(){ synchronized (this) { wait(); // ждать сигнал } sysOut(); } public void sysOut(){ System.out.println("Banana!"); } public void sysOutInThread() { synchronized (this) { notifyAll(); // просигнализировать } } } Основной поток -> t1.start() -> myThread.run() -> myThread.wait() run() уже выполняется в новом потоке t1 Поток t1 "зависает" в wait() Основной поток -> myThread.sysOutInThread() -> myThread.notifyAll() Выполняется всё в основном потоке. notifyAll() посылает сигнал ожидающему потоку t1 wait() в потоке t1 получает сигнал и поток выходит наконец-то из wait() и сразу же принимается выполнять sysOut(). Всё выполняется в потоке t1. На этом работа потока t1 прекращается. Можно зациклить run(), тогда опять будет ждать сигнал, по которому опять сделает sysOut() и так до бесконечности.

Ответ 2



Главное отличие, как по мне, это то, что Runnable - это интерфейс. От Thread же можно только наследоваться. При использовании Runnable унаследоваться вы можете от другого класса. Плюс с Runnable вы можете использовать ThreadPoolExecutor, передавая туда объект своего класса, реализующий Runnable. Если есть возможность, лучше всегда использовать интерфейсы.

Ответ 3



Thread - это собственно сам поток который что то выполняет Runnable - это интерфейс, который съедает поток чтобы что-то выполнить т.е. Thread стремится уйти в парралель и что-то там сделать. Что-то сделать - означает вызвать метод run у переданного ему при создании Runnable объекта.

Комментариев нет:

Отправить комментарий