Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improving concurrently, synchronizing as little as possible.
- Loading branch information
Showing
28 changed files
with
577 additions
and
738 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
124 changes: 62 additions & 62 deletions
124
src/main/java/com/datumbox/common/concurrency/ThreadMethods.java
100644 → 100755
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -1,62 +1,62 @@ | |||
/** | /** | ||
* Copyright (C) 2013-2016 Vasilis Vryniotis <bbriniotis@datumbox.com> | * Copyright (C) 2013-2016 Vasilis Vryniotis <bbriniotis@datumbox.com> | ||
* | * | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | * you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | * You may obtain a copy of the License at | ||
* | * | ||
* http://www.apache.org/licenses/LICENSE-2.0 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
* | * | ||
* Unless required by applicable law or agreed to in writing, software | * Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | * distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | * See the License for the specific language governing permissions and | ||
* limitations under the License. | * limitations under the License. | ||
*/ | */ | ||
package com.datumbox.common.concurrency; | package com.datumbox.common.concurrency; | ||
|
|
||
import java.util.concurrent.ExecutorService; | import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | import java.util.concurrent.Executors; | ||
import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||
import java.util.function.Consumer; | import java.util.function.Consumer; | ||
import java.util.stream.Stream; | import java.util.stream.Stream; | ||
|
|
||
/** | /** | ||
* This class contains a number of helper methods for Java 8 Threads. | * This class contains a number of helper methods for Java 8 Threads. | ||
* | * | ||
* @author Vasilis Vryniotis <bbriniotis@datumbox.com> | * @author Vasilis Vryniotis <bbriniotis@datumbox.com> | ||
*/ | */ | ||
public class ThreadMethods { | public class ThreadMethods { | ||
|
|
||
/** | /** | ||
* Takes the items of the stream in a throttled way and provides them to the | * Takes the items of the stream in a throttled way and provides them to the | ||
* consumer. It uses as many threads as the available processors and it does | * consumer. It uses as many threads as the available processors and it does | ||
* not start more tasks than 2 times the previous number. | * not start more tasks than 2 times the previous number. | ||
* | * | ||
* @param <T> | * @param <T> | ||
* @param stream | * @param stream | ||
* @param consumer | * @param consumer | ||
*/ | */ | ||
public static <T> void throttledExecution(Stream<T> stream, Consumer<T> consumer) { | public static <T> void throttledExecution(Stream<T> stream, Consumer<T> consumer) { | ||
int maxThreads = Runtime.getRuntime().availableProcessors(); | int maxThreads = Runtime.getRuntime().availableProcessors(); | ||
int maxTasks = 2*maxThreads; | int maxTasks = 2*maxThreads; | ||
|
|
||
ExecutorService executorService = Executors.newFixedThreadPool(maxThreads); | ExecutorService executorService = Executors.newFixedThreadPool(maxThreads); | ||
ThrottledExecutor executor = new ThrottledExecutor(executorService, maxTasks); | ThrottledExecutor executor = new ThrottledExecutor(executorService, maxTasks); | ||
|
|
||
stream.forEach(i -> { | stream.sequential().forEach(i -> { | ||
executor.execute(() -> { | executor.execute(() -> { | ||
consumer.accept(i); | consumer.accept(i); | ||
}); | }); | ||
}); | }); | ||
|
|
||
executorService.shutdown(); | executorService.shutdown(); | ||
try { | try { | ||
executorService.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); | executorService.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); | ||
} | } | ||
catch (InterruptedException ex) { | catch (InterruptedException ex) { | ||
throw new RuntimeException(ex); | throw new RuntimeException(ex); | ||
} | } | ||
} | } | ||
|
|
||
} | } |
144 changes: 72 additions & 72 deletions
144
src/main/java/com/datumbox/common/concurrency/ThrottledExecutor.java
100644 → 100755
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -1,73 +1,73 @@ | |||
/** | /** | ||
* Copyright (C) 2013-2016 Vasilis Vryniotis <bbriniotis@datumbox.com> | * Copyright (C) 2013-2016 Vasilis Vryniotis <bbriniotis@datumbox.com> | ||
* | * | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | * you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | * You may obtain a copy of the License at | ||
* | * | ||
* http://www.apache.org/licenses/LICENSE-2.0 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
* | * | ||
* Unless required by applicable law or agreed to in writing, software | * Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | * distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | * See the License for the specific language governing permissions and | ||
* limitations under the License. | * limitations under the License. | ||
*/ | */ | ||
package com.datumbox.common.concurrency; | package com.datumbox.common.concurrency; | ||
|
|
||
import java.util.concurrent.Executor; | import java.util.concurrent.Executor; | ||
import java.util.concurrent.RejectedExecutionException; | import java.util.concurrent.RejectedExecutionException; | ||
import java.util.concurrent.Semaphore; | import java.util.concurrent.Semaphore; | ||
|
|
||
/** | /** | ||
* The ThrottledExecutor enables us to throttle the input of the executor. This | * The ThrottledExecutor enables us to throttle the input of the executor. This | ||
* can be useful when we don't wish to submit all the tasks at once in order to | * can be useful when we don't wish to submit all the tasks at once in order to | ||
* preserve memory. | * preserve memory. | ||
* | * | ||
* @author Vasilis Vryniotis <bbriniotis@datumbox.com> | * @author Vasilis Vryniotis <bbriniotis@datumbox.com> | ||
*/ | */ | ||
public class ThrottledExecutor implements Executor { | public class ThrottledExecutor implements Executor { | ||
|
|
||
private final Executor wrappedExecutor; | private final Executor wrappedExecutor; | ||
|
|
||
private final Semaphore semaphore; | private final Semaphore semaphore; | ||
|
|
||
/** | /** | ||
* This Executor will block the main thread (when execute() is called) if the | * This Executor will block the main thread (when execute() is called) if the | ||
* number of submitted and unfinished tasks reaches the provided limit. This | * number of submitted and unfinished tasks reaches the provided limit. This | ||
* enabled us to pace the input and reduce memory consumption. | * enabled us to pace the input and reduce memory consumption. | ||
* | * | ||
* @param executor | * @param executor | ||
* @param maxConcurrentTasks | * @param maxConcurrentTasks | ||
*/ | */ | ||
public ThrottledExecutor(Executor executor, int maxConcurrentTasks) { | public ThrottledExecutor(Executor executor, int maxConcurrentTasks) { | ||
this.wrappedExecutor = executor; | this.wrappedExecutor = executor; | ||
this.semaphore = new Semaphore(maxConcurrentTasks); | this.semaphore = new Semaphore(maxConcurrentTasks); | ||
} | } | ||
|
|
||
/** {@inheritDoc} */ | /** {@inheritDoc} */ | ||
@Override | @Override | ||
public void execute(final Runnable command) { | public void execute(final Runnable command) { | ||
try { | try { | ||
semaphore.acquire(); | semaphore.acquire(); | ||
} | } | ||
catch (InterruptedException ex) { | catch (InterruptedException ex) { | ||
throw new RuntimeException(ex); | throw new RuntimeException(ex); | ||
} | } | ||
|
|
||
try { | try { | ||
wrappedExecutor.execute(() -> { | wrappedExecutor.execute(() -> { | ||
try { | try { | ||
command.run(); | command.run(); | ||
} | } | ||
finally { | finally { | ||
semaphore.release(); | semaphore.release(); | ||
} | } | ||
}); | }); | ||
} | } | ||
catch (RejectedExecutionException ex) { | catch (RejectedExecutionException ex) { | ||
semaphore.release(); | semaphore.release(); | ||
throw new RuntimeException(ex); | throw new RuntimeException(ex); | ||
} | } | ||
} | } | ||
} | } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.