Почему бы не начать нить в конструкторе? Как прекратить?

Я изучаю, как использовать streamи в Java. И я написал class, который реализует Runnable для одновременного запуска другого streamа. Основной stream обрабатывает прослушивание последовательного порта, где, когда второй stream обрабатывает отправку данных на тот же порт.

public class MyNewThread implements Runnable { Thread t; MyNewThread() { t = new Thread (this, "Data Thread"); t.start(); } public void run() { // New Thread code here } 

Там первая нить начинает вторую, как это:

 public class Main { public static void main(String[] args) throws Exception{ new MyNewThread(); // First thread code there } } 

Это работает, но мой компилятор отмечает предупреждение: опасно начинать новый stream в конструкторе. Почему это?

Вторая часть этого вопроса: как, если у меня есть цикл, работающий в одном streamе (stream прослушивания последовательного порта), и я набираю команду exit во втором streamе. Как я могу завершить первый stream? Благодарю.

К вашему первому вопросу: запуск streamа в конструкторе, проходящем в this ускользает от this . Это означает, что вы фактически выдаете ссылку на свой объект, прежде чем он будет полностью построен. Поток начнется до завершения вашего конструктора. Это может привести к любым видам странного поведения.

К вашему второму вопросу: нет приемлемого способа заставить другой stream останавливаться на Java, поэтому вы должны использовать переменную, которую stream проверял бы, стоит ли останавливаться или нет. Другой stream установил бы его, чтобы указать, что первый stream остановится. Переменная должна быть нестабильной или все обращения синхронизированы для обеспечения правильной публикации. Вот какой код, который будет похож на то, что вы хотите.

 public class MyNewThread implements Runnable { private final Thread t; private volatile boolean shouldStop = false; MyNewThread() { t = new Thread (this, "Data Thread"); } public void start() { t.start(); } public void stop() { shouldStop = true; } public void run() { while(!shouldStop) { // do stuff } } } в public class MyNewThread implements Runnable { private final Thread t; private volatile boolean shouldStop = false; MyNewThread() { t = new Thread (this, "Data Thread"); } public void start() { t.start(); } public void stop() { shouldStop = true; } public void run() { while(!shouldStop) { // do stuff } } } 

Независимо от того, что хочет создать и запустить stream, выполните:

 MyNewThread thread = new MyNewThread(); thread.start(); 

Независимо от того, что хочет остановить stream, выполните:

 thread.stop(); 

Давайте рассмотрим базовый пример:

 class MyClass implements Runnable{ int a = 0; String b = null; public MyClass(){ new Thread(this).start(); b = "Foo"; } public void run(){ a = b.length(); //can throw NullPointerException } } 

В этом случае MyClass.this, как говорят, избегает конструктора. Это означает, что объект доступен для ссылки, но все его поля, которые строятся в конструкторе, могут не создаваться. Чтобы сделать это на другом уровне, если б был final вы ожидаете, что он будет доступен, но он не будет обеспечен. Это известно как частично построенные объекты и совершенно легально в java.

о втором вопросе, вы можете проверить, был ли второй stream завершен или нет методом isAlive и если да, используйте ключевое слово break чтобы отключить цикл для первого streamа, тогда будет прекращено, если ничего не нужно делать

 public class MyNewThread implements Runnable { Thread t; MyNewThread() { t = new Thread (this, "Data Thread"); t.start(); } public void run() { reading code ................ // New Thread code here } 

 public class Main { public static void main(String[] args) throws Exception{ MyNewThread thread = new MyNewThread(); while(true) { listening code ................... if(!thread.t.isAlive()) break; } } } в public class Main { public static void main(String[] args) throws Exception{ MyNewThread thread = new MyNewThread(); while(true) { listening code ................... if(!thread.t.isAlive()) break; } } } 

Вторая часть этого вопроса: как, если у меня есть цикл, работающий в одном streamе (stream прослушивания последовательного порта), и я набираю команду exit во втором streamе. Как я могу завершить первый stream?

Продолжайте цикл, пока не будет достигнуто условие. Например:

 public void run() { while ( !inputConsole.getCommand().equals("exit") ) { //Do Something Thread.sleep(1000); //put thread to sleep for 1 second } } 
Давайте будем гением компьютера.