Комментарии (14)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Semen Bondarenko
Уровень 23
11 декабря 2019, 20:47
Если мы хотим «обернуть» вызовы методов какого-то объекта своим кодом, то нам нужно: 1) Создать свой класс-обертку и унаследоваться от того же класса/интерфейса что и оборачиваемый объект. 2) Передать оборачиваемый объект в конструктор нашего класса. 3) Переопределить все методы в нашем новом классе, и вызвать в них методы оборачиваемого объекта. 4) Внести свои изменения «по вкусу»: менять результаты вызовов, параметры или делать что-то еще. В примере ниже мы перехватываем вызов метода getName у объекта cat и немного меняем его результат.
Semen Bondarenko
Уровень 23
8 декабря 2019, 16:24
Если вы записываете данные в переменную, которая может быть затем прочитана другим потоком, или читаете данные из переменной, которая могла быть записана другим потоком, вы должны использовать синхронизацию. Кроме того, и читающий, и записывающий потоки должны синхронизироваться по одной блокировке.
Semen Bondarenko
Уровень 23
6 декабря 2019, 20:10
Сравнение используется различными алгоритмами от сортировки и двоичного поиска до поддержания порядка в сортированных коллекциях вроде TreeMap. Эти алгоритмы завязаны на три важных свойства сравнивающей функции: рефлексивность (сравнение элемента с самим собой всегда даёт 0), антисимметричность (сравнение A с B и B с A должны дать разный знак) и транзитивность (если сравнение A с B и B с C выдаёт одинаковый знак, то и сравнение A с C должно выдать такой же). Если сравнивающая функция не удовлетворяет этим свойствам, алгоритм может выдать совершенно непредсказуемый результат.
Semen Bondarenko
Уровень 23
3 декабря 2019, 13:05
Volatile же выполняет иную функцию: предположим что синхронизация реализована, а Volatile не стоит: 1й поток (за выполнение которого, предположим, отвечает первое ядро процессора) добавляет в Список нового человека, но сохраняет обновленный список в свою локальную память(кэш), 2й поток (2е ядро) видит что мютекс объекта освободился и начинает читать инфу по всем людям в списке, но так как обновленный Список находится не в общей памяти, а пока еще в локальной памяти первого ядра, в консоль выводится устаревшая информация. Volatile же гарантирует нам то, что обновленный список попадает сразу в общую память и мы избегаем таких казусов.
Semen Bondarenko
Уровень 23
2 декабря 2019, 19:22
Для класса TestedThread создан конструктор в котором выполняется установка setUncaughtExceptionHandler(handler) и, может показаться, что этого достаточно. Но далее мы создаем две нити threadA и threadB, передавая им в качестве параметра объект класса commonThread. Который при передаче сужается до объекта Runnable(смотря аргументы конструктора Thread). Таким образом информация об необходимом обработчике не поступает в конструктор нитей. Для того чтобы всетаки установить обработчик, после создания нитей надо явно указать для них обработчики строками threadA.setUncaughtExceptionHandler(handler); и threadB.setUncaughtExceptionHandler(handler);
Semen Bondarenko
Уровень 23
2 декабря 2019, 14:54
метод setUncaughtExceptionHandler вызывается для текущего объекта и установленный на нём хэндлер не передасться другому объекту, которому мы передадим свой (наш поток); - метод setDefaultUncaughtExceptionHandler ставит хэндлеры по-умолчанию на все потоки, которые включает передаваемый наш поток. Не рекомендуется, если на новые потоки вы ставите разные обработчики.
Semen Bondarenko
Уровень 23
2 декабря 2019, 12:49
Вложенный интерфейс может быть объявлен как public, private или protected. Этим он от­личается от интерфейса верхнего уровня, который должен бьrгь объявлен как pub­lic или использовать уровень доступа по умолчанию. Когда вложенный интерфейс используется за пределами объемлющей его области дей­ствия, его имя должно быть дополнительно уточнено именем класса или интерфей­са, членом которого он является.
Semen Bondarenko
Уровень 23
2 декабря 2019, 11:49
Поток - это теоретически бесконечный поток данных. Можно читать данные из потока или записывать данные в поток. Поток соединяется или с источником данных или с адресатом данных. Потоки могут быть байтовыми (InputStream/OutputStream) или символьными (Reader/Writer). Если программе нужно считать данные откуда-либо, то ей нужен InputStream или Reader. Если программе нужно записать данные куда-либо, то ей нужен OutputStream или Writer.
Semen Bondarenko
Уровень 23
29 ноября 2019, 09:55
Тип ссылки определяет какие методы и состояния класса доступны, а вот сам класс отвечает за реализацию этих методов. Поля не переопределяются, они лишь добавляются. Переопределить можно начальное значение поля. Это можно сделать в конструкторе.
Semen Bondarenko
Уровень 23
28 ноября 2019, 11:53
В данном (да и вообще) случае reader.ready() банально проверяет - а есть ли что-то в буфере, что можно считать. Если да - возвращает "true" и дает дорогу считать эти данные, если нет - возаращает "false" и не дает методу, который считывает данные, считывать пустые строки или висеть в бесконечном ожидании.