Первый поток занимается выращиванием фрукта для второго потока, из которого тот должен приготовить стейк. Промышленные мощности второго потока с самого начала стоят под парами и готовы к работе. Но стейк они могут произвести только из спелого фрукта. Фрукт этот созревает за один день, важно только, чтобы этот день был солнечным, что в данной местности случатся не часто. Поэтому второй поток уходит в режим ожидания пока фрукт не созреет, а первый поток уходит в режим ожидания, пока не выглянет солнце.
Второй поток уходит в режим ожидания с помощью метода wait() объекта Фрукт, прежде чем вызвать этот метод он должен заполучить его монитор, поэтому этот метод обёрнут в блок
synchronized(fruit){
fruit.wait();
}
Первый поток, вырастив фрукт и желая получить готовый стейк должен разбудить второй поток, и делает он это с помощью метода ntify() объекта Фрукт, который также должен быть обёрнут в синхронизованный блок:
synchronized(fruit){
fruit.notify();
}
Полный код примера:
package ru.andrewyakovlev.quizfultest;
public class ThreadsTest {
public static void main(String[] args) {
System.out.println("Начал работу первый поток по выращиванию фрукта");
Fruit fruit = new Fruit();
Thread t = new Thread(){
public void run(){
System.out.println("\t\t Второй поток в полной готовности к получению фрукта и приготовлению из него стейка.");
while(fruit.getMaturity() == "green"){
System.out.println("\t\t Второй поток: фрукт ещё зелёный => ждём...");
try {
synchronized(fruit){
fruit.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("\t\t Второй поток: получен зрелый фрукт, СТЕЙК ПРИГОТОВЛЕН!");
}
};
t.start();
int i = 1;
while(fruit.getMaturity() == "green"){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(Math.random() > 0.75){
System.out.println("Первый поток: на " + i + " день фрукт созрел.");
fruit.setMaturity("red");
synchronized(fruit){
fruit.notify();
}
}else{
System.out.println("Первый поток: " + i++ + " день дождливо.");
}
}
System.out.println("Первый поток закончил выращивание фрукта.");
}
}
class Fruit{
String maturity = "green";
public String getMaturity() {
return maturity;
}
public void setMaturity(String maturity) {
this.maturity = maturity;
}
}
Поскольку в данном примере второму потоку для начала работы нужно дождаться окончания работы первого потока, то в данном случае мы можем сделать синхронизацию с помощью метода join(): мы убираем все синхронизованные блоки, в начале работы программы определяем ссылку на главный поток:
Thread mainThread = Thread.currentThread();
Поскольку в данном примере второму потоку для начала работы нужно дождаться окончания работы первого потока, то в данном случае мы можем сделать синхронизацию с помощью метода join(): мы убираем все синхронизованные блоки, в начале работы программы определяем ссылку на главный поток:
Thread mainThread = Thread.currentThread();
и в начале работы второго потока присоединяем его к первому:
mainThread.join();
Что означает, что продолжение выполнения этого потока начнётся только после завершения главного. Вот полный код:
package ru.andrewyakovlev.quizfultest;
public class ThreadsJoinTest {
public static void main(String[] args) {
System.out.println("Начал работу первый поток по выращиванию фрукта");
Thread mainThread = Thread.currentThread();
Fruit fruit = new Fruit();
Thread t = new Thread(){
public void run(){
System.out.println("\t\t Второй поток в полной готовности к получению фрукта и приготовлению из него стейка.");
try {
mainThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\t\t Второй поток: получен зрелый фрукт, СТЕЙК ПРИГОТОВЛЕН!");
}
};
t.start();
int i = 1;
while(fruit.getMaturity() == "green"){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(Math.random() > 0.75){
System.out.println("Первый поток: на " + i + " день фрукт созрел.");
fruit.setMaturity("red");
}else{
System.out.println("Первый поток: " + i++ + " день дождливо.");
}
}
System.out.println("Первый поток закончил выращивание фрукта.");
}
}
Комментариев нет:
Отправить комментарий