Что может вызвать IllegalMonitorStateException изнутри синхронизированного блока?

Это флаг чувствительности к регистру для селекторов атрибутов, введенный в Селекторах 4 . По-видимому, они включили реализацию этой функции в Chrome уже в августе 2014 года.

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

Вот соответствующие коммиты:

  • 179370 - реализация
  • 179401 - изменения в таблицах стилей UA, как показано в скриншот в вопросе

Обратите внимание, что в настоящее время он скрыт в флагове «Включить экспериментальную веб-платформу», доступ к которому вы можете получить в chrome: // flags / # enable-experimental-web- платформа-функция. Это может объяснить, почему эта функция осталась в значительной степени незаметной - функции, скрытые за этим флагом, могут использоваться только внутри, а не в публичном коде (например, стили стилей автора), если только они не включены, потому что они являются экспериментальными и поэтому не готовы к использованию в производстве.

Вот пример, который вы можете использовать - сравнить результаты, когда флаг включен и отключен:

span[data-foo="bar"] {
    color: red;
}

span[data-foo="bar" i] {
    color: green;
}
If all of this text is green,
your browser supports case-insensitive attribute selectors.

Обратите внимание, что вместо атрибута type я использую атрибут пользовательских данных, чтобы показать, что он может использоваться практически с любым атрибутом.

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

30
задан Chris Aldrich 23 September 2011 в 17:07
поделиться

2 ответа

http://svn.apache.org/viewvc/river/jtsk/trunk/src/com/sun/jini/jeri/internal/mux/Mux.java?r1=1069292&r2=1135026& diff_format = h

здесь я могу видеть, что тайм-аут был добавлен недавно

, убедитесь, что startTimeout> 0, иначе вы будете ждать (0) или ждать (-n) это вероятно причиной IllegalMonitorStateException

РЕДАКТИРОВАТЬ: ОК, выше, это катастрофа, но давайте попробуем это:

мы в конструкторе Mux: http://svn.apache.org /viewvc/river/jtsk/trunk/src/com/sun/jini/jeri/internal/mux/Mux.java?view=markup

в строке 176 мы создаем SocketChannelConnectionIO и передаем это после этого мы сломать и и другая нить вступает во владение.

в конструкторе SocketChannelConnectionIO, определенном здесь: http://svn.apache.org/viewvc/river/jtsk/trunk/src/com/sun/jini/jeri/internal/mux/SocketChannelConnectionIO. java? view = markup строка 112 мы регистрируем на канал с новым обработчиком ().

Обработчик возвращает что-то по каналу, и функция, скажем, выполняется функция handleReadReady, мы синхронизируемся по muxLock.

Теперь мы все еще в конструкторе, поэтому объект в финале все еще изменчив! давайте предположим, что это изменится, теперь у нас есть что-то, ожидающее на другом muxLock

Сценарий один на миллион

РЕДАКТИРОВАТЬ

http: // svn.apache.org/viewvc/river/jtsk/trunk/src/com/sun/jini/jeri/internal/mux/Mux.java?revision=1135026&view=co

Mux(SocketChannel channel,
    int role, int initialInboundRation, int maxFragmentSize)
    throws IOException
    {
    this.role = role;
    if ((initialInboundRation & ~0x00FFFF00) != 0) {
        throw new IllegalArgumentException(
        "illegal initial inbound ration: " +
        toHexString(initialInboundRation));
    }
    this.initialInboundRation = initialInboundRation;
    this.maxFragmentSize = maxFragmentSize;

    //LINE BELOW IS CAUSING PROBLEM it passes this to SocketChannelConnectionIO
    this.connectionIO = new SocketChannelConnectionIO(this, channel);

    //Lets assume it stops here we are still in constructor
    //and we are not in synchronized block

    directBuffersUseful = true;
    }

теперь в конструкторе SocketChannelConnectionIO http://svn.apache.org/viewvc/river/jtsk/trunk/src/com/sun/jini/jeri/internal/mux/SocketChannelConnectionIO.java?revision=1069292&view = co

SocketChannelConnectionIO(Mux mux, SocketChannel channel)
    throws IOException
{
    super(mux);
    channel.configureBlocking(false);
    this.channel = channel;
    //Line below we are registering to the channel with mux that is still mutable
    //this is the line that actually is causing the problem move that to 
    // start() and it should work 
    key = selectionManager.register(channel, new Handler());
}

переместить этот код в start () должно работать key = selectionManager.register(channel, new Handler()); (я предполагаю, что start is executet, когда мы хотим начать обработку)

/**
 * Starts processing connection data.
 */
void start() throws IOException {
    key = selectionManager.register(channel, new Handler());
    key.renewInterestMask(SelectionKey.OP_READ);
}

Но было бы намного лучше не создавать SocketChannelConnectionIO в конструкторе mux, но может быть где-то после этого то же самое для второго конструктора, создающего StreamConnectionIO с этим

2
ответ дан firegnom 23 September 2011 в 17:07
поделиться

Переменные-члены не так окончательны, как хотелось бы. Сначала вы должны поместить синхронизированный объект в конечную локальную переменную. Это не объясняет, почему переменная-член изменена, но если она решает проблему, вы, по крайней мере, знаете, что переменная-член действительно изменена.

1
ответ дан Christian 23 September 2011 в 17:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: