середа, 9 березня 2011 р.

Многопоточность. Wait / notify и приоритеты при захвате монитора. Spurious wakeups

javenue поставил точку в нашем споре, написав замечательную статью. Суть спора сводится к тому что поток, выходящий из wait-set монитора, имеет приоритет над другими потоками из очереди этого монитора.

Читайте детальное описание проблемы здесь

вівторок, 8 березня 2011 р.

Как выглядит счетчик в байт-коде?

Начав глубже копать многопоточность, захотел разобраться с байт-кодом и общими принципами работы JVM. Эта заметка дает общее представление о том, что такое байт-код и что он из себя представляет, и продемонстрирует неатомарность операции инкремента.

Что такое байт-код?

Байт-код - это инструкции интерпретатору Java-машины, своего рода ассемблерный язык.
Рассмотрим простой класс - счетчик, значение которого можно увеличить или уменьшить.

// Counter.java
public class Counter {
    private int counter = 0;

    public int inc() {
        return ++counter;
    };

    public int dec() {
        return --counter;
    }

    public int getValue() {
        return counter;
    }

    public static void main(String[] args) {
        Counter c = new Counter();
        System.out.println(c.inc());
    }
}

Скомпилировав его в Counter.class, мы можем теперь декомпилировать класс в байт-код с помощью утилиты javap

grim@blackbox:~/projects/privy/trunk/scl/sourcepath$ javap -c Counter

Compiled from "Counter.java"
public class Counter extends java.lang.Object{
public Counter();
  Code:
   0: aload_0
   1: invokespecial #1; //Method java/lang/Object."<init>":()V
   4: aload_0
   5: iconst_0
   6: putfield #2; //Field counter:I
   9: return

public int inc();
  Code:
   0: aload_0
   1: dup
   2: getfield #2; //Field counter:I
   5: iconst_1
   6: iadd
   7: dup_x1
   8: putfield #2; //Field counter:I
   11: ireturn

public int dec();
  Code:
   0: aload_0
   1: dup
   2: getfield #2; //Field counter:I
   5: iconst_1
   6: isub
   7: dup_x1
   8: putfield #2; //Field counter:I
   11: ireturn

public int getValue();
  Code:
   0: aload_0
   1: getfield #2; //Field counter:I
   4: ireturn

public static void main(java.lang.String[]);
  Code:
   0: new #3; //class Counter
   3: dup
   4: invokespecial #4; //Method "<init>":()V
   7: astore_1
   8: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
   11: aload_1
   12: invokevirtual #6; //Method inc:()I
   15: invokevirtual #7; //Method java/io/PrintStream.println:(I)V
   18: return

}

Байт-код как мы видим - это поток инструкций JVM. Каждая инструкция состоит из кода операции и опционально от одного до нескольких операндов.

Дальше приведу краткий разбор метода inc():

0 aload_0                              ; загружаем ссылку на экземпляр обьекта из переменной и толкаем ее в стек
 1 dup                                  ; копируем верхний элемент стека и толкаем его в стек
 2 getfield #2 <counter.counter>        ; извлекаем из стека ссылку, получаем у нее поле counter (в пуле констант имеет номер #2), и толкаем это значение в стек
 5 iconst_1                             ; толкаем в стек константу-единицу
 6 iadd                                 ; извлекаем два верхних элемента стека, выполняем сложение, результат толкаем в стек
 7 dup_x1                               ; копируем верхний элемент стека и размещаем его перед вторым элементом в стеке
 8 putfield #2 <counter.counter>        ; извлекаем из стека последовательно значение и ссылку на экземпляр, устанавливаем новое значение поля counter
11 ireturn                              ; извлекаем из стека значение и интерпретатор передает контроль вызывающему методу.


Как видно одна операция инкремента скомпилировалась в целых 6 инструкций (со 2 по 8). Это и есть пресловутая неатомарность операции. Один из последствий неатомарности при вызове метода из нескольких потоков возможно несогласованное чтение одного и того же значения, что приведет к возврату одного и того же значения обоими потоками, что противоречит контракту inc().

На этом завершаю, ибо нашел замечательную статью Антона Архипова Java Bytecode Fundamentals (на английском языке). Лучше, чем он, пожалуй, про байт-код расписать не смогу.

Ссылки

Bytecode Basics A First Look at the Bytecodes of the Java Virtual Machine by Bill Venners

The JavaTM Virtual Machine Specification Second Edition Tim Lindholm Frank Yellin

Java Bytecode Fundamentals by Anton Arhipov

четвер, 3 березня 2011 р.

Amazon Kindle: перші враження

Став щасливим власником читалочки Kindle. Замовив у неділю і вже у четвер кур’єр привіз пакуночок прямо мені на роботу. Що я можу сказати? Сервіс у Амазона на висоті. Незважаючи на певну зневагу до нашої країни більшості закордонних компаній, сервіс від Амазона приємно вразив. Мабуть чи не вперше в житті, річ, яку придбав, приносить самі лише позитивні враження, від найпершого моменту як я зайшов на Амазон у неділю і до цього самого моменту часу.

Загальний вигляд

Фотки в мене немає, знайдете валом їх в інтернеті. Скажу лише, що мій графітовий. Взяв до нього ще обкладинку з підсвіткою - найпопулярніший, з їх слів, комплект. Обкладинка оснащена діодною підсвіткою, яка на перший погляд, слабенька, але вночі в темноті в маршрутці читати було дуже комфортно, навіть комфортніше, ніж у нашому освтленому жовтавим світлом метро.

Контрастність екрану дуже залежить від зовнішнього освітлення, іноді читати дуже важко, особливо при приглушеному жовтуватому світлі. Чесно кажучи, чекав трохи більше контрасту, але такий у більшості пристроїв, і Амазон тут не виявився винятком.

Зручно, що кнопки листання книги дубльовані з обох боків пристрою. Сама QWERTY-клавіатура не з найзручніших, але не є зайвою ні в якому разі. Без неї набір адрес веб-сторінок та підключення до Wi-Fi були б катастрофічно незручними.

Зв’язок

З інших приємностей порадувала підтримка 3G прямо з коробки. Я очікував, що доведеться оплачувати щомісячні рахунки за інет, - нічого подібного. Пристрій одразу поліз на Амазон, зареєструвався, з мого боку налаштувань взагалі не було. Це було б навіть не в тему, бо я був занадто зайнятий самим девайсом, вертінням його у руках та показами для колег )

Як я розумію, Амазон робить ставку на продажі електронних книг онлайн, і це, в принципі, досить влучний розрахунок. Я не втримався теж і, - трохи для фану, а трохи й для діла - придбав кілька книг, які давно хотів, але не наважувався, замовити - все таки витратити 20 баксів за доставку книги вартістю 30 баксів - трохи занадто.

Так от книги купуються в один клік - буквально. Один клік - і через кілька секунда книга вже готова до читання. Це не те щоб фантастика, таке давно було можливе, але для мене це все одно було шоком на власні очі спробувати ті можливості Інтернет, потенціал яких назрівав уже давно.

Пітримка Wi-Fi також на борту - без проблем заграла моя домашня мережа.

Функціональність

На борту також експериментальний веб-оглядач та MP3-плеєр. Сторінки рендеряться в цілому коректно, хоча послухати музику через флеш-програвачі не вийде.
Сьорфінг настільки зручний, наскільки може бути зручною навігація клавішами. Інтернет не обмежується, що для парубка з Украіни дивно і приємно.

В цілому я не помітив ні органайзера, ні інших бубликів, які відволікатимуть мене від основного заняття - читання. Комусь це може не сподобатись, але мені начхать на бублики.

Формати

Болюча тема, Підтримуються PDF, TXT, MOBI та ще кілька. Я вже очікую, як буду прикручувати підтримку fb2, яка відсутня. Що трохи напрягло - так це те, що скачати PDF з інтернету не вдалося через внутрішнє обмеження в браузері - довелося висилати поштою.

Загалом

Довольний, як слон. Скільки годин в транспорті тепер не втрачені для мене - важко уявити, а цікавих книжок вистачить на все життя!