Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
# java_homeworks
### Запуск jcstress

```
mvn clean install

java -jar target/jcstress.jar
```
127 changes: 127 additions & 0 deletions simpleThreadPool/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<!--
Copyright (c) 2017, Red Hat Inc.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

* Neither the name of Oracle nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>1</groupId>
<artifactId>simpleThreadPool</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>JCStress test sample</name>

<!--
This is the demo/sample template build script for building concurrency tests with JCStress.
Edit as needed.
-->

<prerequisites>
<maven>3.0</maven>
</prerequisites>

<dependencies>
<dependency>
<groupId>org.openjdk.jcstress</groupId>
<artifactId>jcstress-core</artifactId>
<version>${jcstress.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<!--
jcstress version to use with this project.
-->
<jcstress.version>0.4</jcstress.version>

<!--
Java source/target to use for compilation.
-->
<javac.target>1.8</javac.target>

<!--
Name of the test Uber-JAR to generate.
-->
<uberjar.name>jcstress</uberjar.name>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<compilerVersion>${javac.target}</compilerVersion>
<source>${javac.target}</source>
<target>${javac.target}</target>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>main</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>${uberjar.name}</finalName>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.openjdk.jcstress.Main</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/TestList</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package simpleThreadPool;

public class LightExecutionException extends Exception {}
12 changes: 12 additions & 0 deletions simpleThreadPool/src/main/java/simpleThreadPool/LightFuture.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package simpleThreadPool;

import java.util.function.Function;

public interface LightFuture<R> {

public boolean isReady();

public R get() throws LightExecutionException, InterruptedException;

public <R1> LightFuture<R1> thenApply(Function<R, R1> nextFunc);
}
48 changes: 48 additions & 0 deletions simpleThreadPool/src/main/java/simpleThreadPool/SubmitGetTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package simpleThreadPool;

import java.util.Random;

import org.openjdk.jcstress.annotations.*;
import org.openjdk.jcstress.infra.results.II_Result;
import org.openjdk.jcstress.infra.results.I_Result;

@JCStressTest
@Outcome(id = "0, 0", expect = Expect.ACCEPTABLE, desc = "Good outcome.")
@State
public class SubmitGetTest {

static ThreadPool pool = new ThreadPoolImpl(2);
Random rand = new Random(10);

void filler(II_Result r) {
Integer rnd = rand.nextInt();
LightFuture<Integer> f1 = pool.submit(() -> rnd);
LightFuture<Integer> f2 = f1.thenApply((i) -> i + 1);
try {
r.r1 = rnd - f1.get();
r.r2 = rnd + 1 - f2.get();
} catch (LightExecutionException | InterruptedException e) {
int i = 1/0;
}
}

@Actor
public void actor1(II_Result r) {
filler(r);
}

@Actor
public void actor2(II_Result r) {
filler(r);
}

@Actor
public void actor3(II_Result r) {
filler(r);
}

@Actor
public void actor4(II_Result r) {
filler(r);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package simpleThreadPool;

import java.util.function.Supplier;

import simpleThreadPool.Worker.LightFutureImpl;

public class SupplierFuturePair {
Supplier supplier;
LightFutureImpl future;

public SupplierFuturePair(Supplier suppl, LightFutureImpl fut) {
supplier = suppl;
future = fut;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package simpleThreadPool;

import java.util.function.Supplier;

public interface ThreadPool {
public <R> LightFuture<R> submit(Supplier<R> supp);

public void shutdown();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package simpleThreadPool;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.function.Supplier;

import simpleThreadPool.Worker.LightFutureImpl;

public class ThreadPoolImpl implements ThreadPool{

private Queue<SupplierFuturePair> tasks = new LinkedList<>();

private List<Thread> pool = new ArrayList<>();

public ThreadPoolImpl(int nthreads) {
for (int i = 0; i < nthreads; i++) {
Thread t = new Thread(new Worker(tasks));
t.setDaemon(true);
pool.add(t);
t.start();
}
}

@Override
public <R> LightFuture<R> submit(Supplier<R> supp) {
SupplierFuturePair pair = new SupplierFuturePair(supp,
new LightFutureImpl(this));

synchronized (tasks) {
tasks.add(pair);
tasks.notify();
}

return pair.future;
}

@Override
public void shutdown() {
for (Thread t : pool) {
t.interrupt();
}
}
}
94 changes: 94 additions & 0 deletions simpleThreadPool/src/main/java/simpleThreadPool/Worker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package simpleThreadPool;

import java.util.Queue;
import java.util.function.Function;

public class Worker implements Runnable {

private Queue<SupplierFuturePair> queue;

public Worker(Queue<SupplierFuturePair> q) {
queue = q;
}

static class LightFutureImpl<R> implements LightFuture<R> {
private volatile boolean isready;
private ThreadPool masterPool;

private R result;
private LightExecutionException execExcept;

public LightFutureImpl(ThreadPool tp) {
masterPool = tp;
}

@Override
public boolean isReady() {
return isready;
}

@Override
public R get() throws LightExecutionException, InterruptedException {
if (!isready) {
synchronized (this) {
while (!isready) {
this.wait();
}
}
}

if (execExcept != null) {
throw execExcept;
}

return result;
}

@Override
public <R1> LightFuture<R1> thenApply(Function<R, R1> nextFunc) {
return masterPool.submit(() -> {
R1 res = null;
try {
res = nextFunc.apply(get());
} catch (Exception e) {
throw new RuntimeException();
}
return res;
});
}

}

@Override
public void run() {
a: while (true) {
SupplierFuturePair workPair;

synchronized (queue) {
while (queue.isEmpty()) {
try {
queue.wait();
} catch (InterruptedException e) {
break a;
}

}
workPair = queue.poll();
}

LightFutureImpl future = workPair.future;
synchronized (future) {

try {
future.result = workPair.supplier.get();
} catch (Exception e) {
future.execExcept = new LightExecutionException();
}

future.isready = true;
future.notifyAll();
}
}
}

}
Loading