Почему у моего файла есть условия гонки, хотя я использовал Standardopenoption.sync?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Почему у моего файла есть условия гонки, хотя я использовал Standardopenoption.sync?

Сообщение Anonymous »

У меня есть файл CSV, который слишком большой, чтобы вписаться в оперативную память, и едва ли только подходит на мой жесткий диск. Мне нужно разделить этот файл CSV на части. > выписать детали. Я понимаю, что это может быть не идеально, но, честно говоря, задача под рукой на самом деле не является точкой. >. Вот мой код. < /P>

Код: Выделить всё

import java.nio.file.*;
import java.util.function.*;
import java.util.stream.*;
import java.util.*;

import static java.nio.file.StandardOpenOption.*;

public class temp2
{

public static final Path parentFolder =
Path
.of(".")
.toAbsolutePath()
.normalize()
;

public static void main(final String[] args) throws Exception
{

System.out.println(parentFolder);

for (int i = 0; i < 10; i++)
{

Files.deleteIfExists(parentFolder.resolve(String.valueOf(i)));

}

final int LIMIT = 100_000;
final HashMap blahs =
IntStream
.range(0, 100_000_000)
.parallel()
.mapToObj(String::valueOf)
.collect
(
Collector
.of
(
HashMap::new,
(map, s) ->
{

final String key = String.valueOf(s.charAt(0));
final List list = map.compute(key, (k, v) -> v == null ? new ArrayList() : v);
list.add(s);

if (list.size() > LIMIT)
{

writeThenClearList(key, list);

}

},
(HashMap oldMap, HashMap newMap) ->
{

System.out.println(oldMap.values().stream().flatMap(Collection::stream).count());
System.out.println(newMap.values().stream().flatMap(Collection::stream).count());
System.out.println("---");

oldMap.forEach(temp2::writeThenClearList);
newMap.forEach(temp2::writeThenClearList);
return new HashMap();
},
(map) ->
{

map.forEach(temp2::writeThenClearList);

return map;

}
)
)
;
blahs.entrySet().forEach(System.out::println);

}

private static void writeThenClearList(final String key, final List list)
{

if (list.isEmpty())
{

return;

}

try {
Files
.write(
parentFolder.resolve(key),
list,
StandardOpenOption.CREATE,
StandardOpenOption.WRITE,
StandardOpenOption.APPEND,
StandardOpenOption.SYNC
);
} catch (final Exception e) {
throw new RuntimeException(e);
}

list.clear();

}

}
< /code>
Написание было довольно простым - он просто генерирует все числа от 0 до 100 миллионов, а затем группирует их в файлы на основе начальной цифры. Итак, 0 переходит в файл te 0, 1 заходит в файл 1, 10 заходит в 1 -й файл, 20 заходит в 2 -й файл, 300 заходит в 3 -й файл и т. Д. < /p>
Я также особо заботился о использовании standardopenoption.sync 
, чтобы убедиться, что мои записи происходили синхронно. код. Я использовал jshell , но я также получил те же результаты, запустив его как обычный файл.

Код: Выделить всё

IntStream
.range(0, 10)
.mapToObj(String::valueOf)
.map(Path::of)
.map
(
path ->
{
try
{
return Files.lines(path);
}

catch (final Exception e)
{
throw new RuntimeException(e);
}
}
)
.map
(
stream ->
stream
.filter(s -> !s.equals(""))
.mapToLong(Long::parseLong)
.summaryStatistics()
)
.forEach(System.out::println)
;

Все, что это делает, распечатана Longsummarystatistics для каждого из 10 файлов.
Вот каким был мой выход.

Код: Выделить всё

LongSummaryStatistics{count=1, sum=0, min=0, average=0.000000, max=0}
LongSummaryStatistics{count=11110722, sum=671067271105847657, min=0, average=60398169543.423700, max=1996215711700017}
LongSummaryStatistics{count=11110807, sum=936118810008566710, min=0, average=84252998905.351040, max=2999558127899730}
LongSummaryStatistics{count=11110948, sum=726950006539566180, min=0, average=65426461049.009155, max=3699881930345059}
LongSummaryStatistics{count=11110761, sum=1580564487107336657, min=0, average=142255286303.731720, max=4980250345042342}
LongSummaryStatistics{count=11110842, sum=1291096623566986753, min=0, average=116201510521.613650, max=5990245950494212}
LongSummaryStatistics{count=11110683, sum=2140046523919170444, min=0, average=192611608478.000000, max=6999483760545061}
LongSummaryStatistics{count=11110881, sum=1629411286034487818, min=0, average=146650052865.698760, max=7993937378575107}
LongSummaryStatistics{count=11110718, sum=3892896980864594155, min=0, average=350373124478.957500, max=8993173987418912}
LongSummaryStatistics{count=11110795, sum=2930254808993867970, min=0, average=263730435940.350620, max=9996168394101800}

< /code>
 


 numprefix < /th>
 count < /th>
 sum < /th>
 min < /th>
 Среднее < /th>
 max < /th>
< /tr>
< /thead>


 0 < /td>
 1 < /td>
 0 < /td>
 0 < /td>
 0,000000 < /td>
 0 < /td>
< /tr>

 1 < /td>
< TD> 11110722 < /td>
 671067271105847657 < /td>
 0 < /td>
60398169543.423700>  1996215711700017 < /td>
< /tr>

 2 < /td>
 11110807 < /td>
 936118810008566710 
 0 
342529998905.351040
 2999558127899730 


 3 < /td>
 11110948 < /td>
 726950006539566180 < /td>
 0 < /td>
65426461049.009155555555555555 > 4 < /td>
 11110761 < /td>
 1580564487107336657 < /td>
 0 < /td>
< /td>
 4980250345042342 < /td>
< /tr>

 5 < /td>
 11110842 < /td>
 1291096623566986753 < /td>
 0 < /td>
116201510521.613650
 5990245950499212121212121212  /td>
< /tr>

 6 < /td>
 11110683 < /td>
 2140046523919170444 
 0 
функциональный /> 
 7 < /td>
 11110881 < /td>
 1629411286034487818 < /td>
 0 < /td>
146650052865.698760
 7993937378575107 < /td>
< /tr>

 8 
 11110718 
 3892896980864594155 
 0 
td>
 8993173987418912 < /td>
< /tr>

 9 < /td>
 11110795 < /td>
 2930254808993867970 < /td>
 0 < /td>
td> 263730435940.350620 < /td>
 996168394101800 < /td>
 996168394101800 < /td> >
< /tr>
< /tbody>
< /table> < /div>
Теперь, что немедленно выскочило, было максимальным значением Для каждого столбца. Это слишком высоко. Некоторые из них сообщали о цифрах в четырехлетних. И, кроме того, у каждого было мин 0. И, кроме того, ни один из случаев не одинаково. Они должны быть такими же, верно? < /P>
Так хорошо, у нас есть состояние гонки. Однако я не понимаю, почему стандартная топенопнопция.sync 
не защитила меня. Разве это не его работа?>

Подробнее здесь: https://stackoverflow.com/questions/794 ... option-syn
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»