#java #многопоточность
Поясните, пожалуйста, где я могу быть не прав. 1. Главный поток main запускает два потока: t1, t2. 2. Поток main останавливается и ждет завершения потоков t1 и t2 так как вызваны методы t1.join и t2.join. 3. Первый поток t1 несколько раз засыпает при выполнении, но второй не может начать выполнения метода writing, так как он synchronized. В результате после работы первого потока в файле имеем запись: First0->0 First1->1 First2->2 First3->3 First4->4 4. После окончания первого потока, второй делает тоже самое. 5. Два потока завершены, поток main завершает выполнение. В результате в файле мы можем иметь только запись вида: First0->0 First1->1 First2->2 First3->3 First4->4 Second0->0 Second1->1 Second2->2 Second3->3 Second4->4 Но в учебнике приводиться другой результат. Как такое возможно? import java.io.FileWriter; import java.io.IOException; /** * Created by IP44 on 25.11.2016. */ class Synchro { private FileWriter fileWriter; public Synchro(String file) throws IOException { fileWriter = new FileWriter(file, true); } public void close() { try { fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } } public synchronized void writing(String str, int i) { try { System.out.print(str + i); fileWriter.append(str + i); Thread.sleep((long)(Math.random() * 50)); System.out.print("->" + i + " "); fileWriter.append("->" + i + " "); } catch (Exception e) { System.err.print("Error of stream"); e.printStackTrace(); } } } class MyThread extends Thread { private Synchro s; public MyThread(String str, Synchro s) { super(str); this.s = s; } public void run() { for (int i = 0; i < 5; i++) { s.writing(getName(), i); } } } public class SynchroThreads { public static void main(String[] args) { try { Synchro s = new Synchro("C:\\Users\\IP44\\Downloads\\data.txt"); MyThread t1 = new MyThread("First", s); MyThread t2 = new MyThread("Second", s); t1.start(); t2.start(); t1.join(); t2.join(); s.close(); } catch (Exception ex) { ex.printStackTrace(); } } }
Ответы
Ответ 1
Только метод write помечен как synchronized, но не метод run, в котором находится цикл. Так что порядок выводв может быть любой. Это можно явно увидеть, если добавить немного ожидания в сам run - если бы порядок был задан блокировками, он бы не поменялся. http://ideone.com/joXG0N public void run() { try { for (int i = 0; i < 5; i++) { s.writing(getName(), i); Thread.sleep((long)(Math.random() * 50)); } } catch (Exception ex) { ex.printStackTrace(); } } First0->0 Second0->0 First1->1 Second1->1 First2->2 Second2->2 First3->3 Second3->3 First4->4 Second4->4 Но в учебнике приводиться другой результат. Там не об этом. Там о том, что System.out.print(str + i); fileWriter.append(str + i); Thread.sleep((long)(Math.random() * 50)); // <-- В этом месте System.out.print("->" + i + " "); fileWriter.append("->" + i + " "); даже несмотря на sleep переключения на другой write не будет. Т. е. мы никогда не увидим такого: First->Second->0->0
Комментариев нет:
Отправить комментарий