Существует потенциал для тонкой ошибки в Вашем коде.
[ ОБНОВЛЕНИЕ: , Так как он использует map.remove () это описание не полностью действительно. Я пропустил тот факт в первый раз через.:( Благодаря автору вопроса для указания на это. Я оставляю остальных, как, но изменил ведущий оператор, чтобы сказать, что существует потенциально ошибка.]
В [1 120] doWork () Вы получаете значение Списка из Карты ориентированным на многопотоковое исполнение способом. Позже, однако, Вы получаете доступ к тому списку в небезопасном вопросе. Например, один поток может использовать список в [1 121] doWork () , в то время как другой поток вызывает synchronizedMap.get (ключ) .add (значение) в [1 123] addToMap () . Те два доступ не синхронизируются. Эмпирическое правило - то, что ориентированные на многопотоковое исполнение гарантии набора не расширяются на ключи или значения, которые они хранят.
Вы могли зафиксировать это путем вставки синхронизируемого списка в карту как [1 111]
List<String> valuesList = new ArrayList<String>();
valuesList.add(value);
synchronizedMap.put(key, Collections.synchronizedList(valuesList)); // sync'd list
, Кроме того, Вы могли синхронизироваться на карте при доступе к списку в [1 124] doWork () :
public void doWork(String key) {
List<String> values = null;
while ((values = synchronizedMap.remove(key)) != null) {
synchronized (synchronizedMap) {
//do something with values
}
}
}
последняя опция ограничит параллелизм немного, но является несколько более ясным IMO.
кроме того, быстрое примечание о ConcurrentHashMap. Это - действительно полезный класс, но является не всегда соответствующей заменой для синхронизируемого HashMaps. При заключении в кавычки из его Javadocs
Этот класс полностью совместим с Хеш-таблицей в программах, которые полагаются на его потокобезопасность , но не в его деталях синхронизации .
, Другими словами, putIfAbsent () является большим для атомарных вставок, но не гарантирует, что другие части карты не изменятся во время того вызова; это гарантирует только атомарность. В Вашем примере программы Вы полагаетесь на детали синхронизации (синхронизируемый) HashMap для вещей кроме помещенного () s.
Последняя вещь.:) Эта большая кавычка от Параллелизм Java на практике всегда помогает мне в разработке отлаживающие многопоточные программы.
Для каждой изменяемой переменной состояния, к которой может получить доступ больше чем один поток, все доступы к той переменной должны быть выполнены с той же сохраненной блокировкой.
Предполагая, что у вас есть HTML-код для таблицы , вы можете просто создать из него объект jQuery и добавить его в DIV. Если у вас есть данные, вам необходимо выполнить итерацию по ним, создать ячейки / строки из данных и добавить их независимо.
$('<table><tr><td>.....</td></tr></table>').appendTo( '#div1' );
или
var data = [ [ 1, 2, 3 ], [ 4, 5, 6 ], [7, 8, 9 ] ];
var html = '<table><thead><tr>...</tr></thead><tbody>';
for (var i = 0, len = data.length; i < len; ++i) {
html += '<tr>';
for (var j = 0, rowLen = data[i].length; j < rowLen; ++j ) {
html += '<td>' + data[i][j] + '</td>';
}
html += "</tr>";
}
html += '</tbody><tfoot><tr>....</tr></tfoot></table>';
$(html).appendTo('#div1');
var newContent = $('<your html="here"/>');
var insertLocation = $('#div1');
insertLocation.append(newContent);
Есть много разных способов вы могли бы пойти с этим. Один из способов - сделать что-то вроде этого:
// $(document).ready() makes sure that nothing happens until the page
// is fully loaded. It's important because the div may not have loaded
// yet if you put code outside of this
$(document).ready( function() {
$("#div1").append(
"<table><tr><td>My column 1, row 1</td>" +
"<td>My column 2, row 2</td></tr>" +
"<tr><td>My column 1, row 2</td>" +
"<td>My column 2, row 2</td></tr></table>");
});
Это поместит полную таблицу в ваш div, обработанную как HTML. Другой способ, если вы хотите добавить каждую строку отдельно, будет:
$(document).ready(function() {
$("#div1").append("<table id=\"my_table1\"></table>");
$("#my_table1").append("<tr><td>Row 1</td></tr>");
... insert more rows here ...
$("#my_table1").append("<tr><td>Row ...</td></tr>");
});
It '