Concurrent writing elements into the ConcurrentHashMap admits element. Requirements: writing must be done in different threads. Is there way to use advantages of the ConcurrentHashMap and do writing without blocking and sleeping?
Is there good code for iterator that accessed from different treads. Or is there other good variant to keep ieratian looking on the effectively-final requirement?
public class Task3v2 {
public static void main(String[] args) {
System.out.println("ConcurrentHashMap : "+timeIt(new ConcurrentHashMap<Integer, String>()));
}
static Iterator<Integer> integerIterator;
static {createIterator();}
private static void createIterator() {
integerIterator=
Stream.iterate(0, i -> i + 1).limit(100).collect(Collectors.toList()).iterator();
}
public static double timer(Runnable block) {
long start = System.nanoTime();
try {
block.run();
} finally {
long end = System.nanoTime();
return(end - start);
}
}
public static double timeIt(Map<Integer, String> map){
return timer(
()->{
new Thread(()->{
fillMap(map);
System.out.println("invoked");
readMap(map);
}).start();
});
}
private static void fillMap(Map<Integer, String> map){
int[] index = new int[1];
String[] tmp = new String[1];
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i = 0; i< 100; i++){
index[0] = i;
tmp[0] = "Name"+i;
new Thread(()->{
int a = integerIterator.next();
System.out.println("a :"+a);
map.put(a,"Name"+a);
}
).start();
}
}
private static void readMap(Map<Integer, String> map){
int[] index2 = new int[1];
for(int i = 0; i< 100; i++){
index2[0]=i;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
System.out.println("map.get(index2[0]) :"+map.get(index2[0]));
}).start();
}
}
}
Finally the map must pass following tests:
public class Task3Test {
static ConcurrentHashMap<Integer, String> map;
#BeforeClass
public static void fillMap(){
map = new ConcurrentHashMap<>();
timeIt(map);
}
#Test
public void elementPresenceTest(){
//GIVEN
//map;
//WHEN
List<Integer> actualPresenceList = Stream.iterate(0, i -> i + 1).limit(100)
.filter(n->(map.entrySet().stream().map(Map.Entry::getKey)
.anyMatch(m->(n.equals(m))))).collect(Collectors.toList());
actualPresenceList.forEach(System.out::println);
System.out.println("size"+actualPresenceList.size());
//THEN
List<Integer>expectedPresenceList = Stream.iterate(0, i -> i + 1).limit(100).collect(Collectors.toList());
assertThat(actualPresenceList, Matchers.contains(expectedPresenceList));
}
#Test
public void elementAmountTest() {
assertThat(map.entrySet(), Matchers.hasSize(100));
}
}
Iterator is not acceptable for concurrency. Solution is:
static Queue integerQueue = Stream.iterate(0, i -> i + 1).limit(100).collect(Collectors.toCollection(LinkedBlockingQueue::new));
There is needed to keep sleeping for the readMap() method to provide time for the writing method. If there is needed to keep any data structure on adding new elements in concurrency environment, it should be used queue instead of map.
Related
I am trying to print even and odd number using two different thread but It is throwing IllegalMonitorStateException .Kindly suggest me what am I doing wrong .
package com.rishi.threading;
public class MyThread {
public static class EvenThread extends Thread {
Boolean evenFlag;
Integer sharedCount;
public EvenThread(Boolean flag, Integer count) {
this.evenFlag = flag;
this.sharedCount = count;
}
public void run() {
printEven();
}
private void printEven() {
for (int i = 0; i < 10; i++) {
synchronized (evenFlag) {
if (!evenFlag) {
try {
evenFlag.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
evenFlag = false;
System.out.println("even thread :" + sharedCount++);
notifyAll();
}
}
}
}
public static class OddThread extends Thread {
Boolean evenflag;
Integer sharedCount;
public OddThread(Boolean flag, Integer count) {
this.evenflag = flag;
this.sharedCount = count;
}
public void run() {
printOdd();
}
private void printOdd() {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++) {
synchronized (evenflag) {
if (evenflag) {
try {
evenflag.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
evenflag = true;
System.out.println("odd thread :" + sharedCount++);
notifyAll();
}
}
}
}
public static void main(String[] args) {
Boolean evenFlag = new Boolean(true);
Integer sharedCount = new Integer(0);
EvenThread thread1 = new EvenThread(evenFlag, sharedCount);
thread1.setName("evenThread");
OddThread thread2 = new OddThread(evenFlag, sharedCount);
thread2.setName("oddthread");
thread1.start();
thread2.start();
}
}
I created two thread "EvenThread" and "OddThread".
Both the thread shares two common member variable ie evenFlag and sharedCount.
evenFlag -> just a flag which is set as true when sharedCount is even and set as false when shareDcount is set to odd number.
So both the thread is trying to get lock of evenFlag to control the printing of sharedCount.
In the example below if I implement ExecutorImpl without using Thread, then taskCompletionService.submit is blocked, even though it returns Future.
Is it possible to not block submit, but not use Thread in ExecutorImpl?
class ExecutorServiceTest {
private static class ExecutorImpl implements Executor {
public void execute(Runnable r) {
final Thread t = new Thread(new Runnable() {
public void run() {
r.run();
}});
t.start();
//If used will block others.
//r.run();
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
final Executor executor = new ExecutorImpl();
final CompletionService<String> taskCompletionService = new ExecutorCompletionService<>(executor);
int submittedTasks = 3;
for(int i = 0; i < submittedTasks; i++) {
final int j = i;
//here it is blocked if ExecutorServiceIml doesn't utilize Thread
taskCompletionService.submit(new Callable<String>() {
public String call() throws Exception {
Thread.sleep((3 - j) * 1000);
return "callable:" + String.valueOf(j);
}
});
System.out.println("Task " + String.valueOf(i) + " has been submitted...");
}
for(int tasksHandled=0; tasksHandled < submittedTasks; tasksHandled++) {
try {
final Future<String> result = taskCompletionService.take();
String l = result.get();
System.out.println("Task has completed - result: " + l);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
}
how can i block the put method when cache reloading is being called.
Example: These are dummy classes not the actual.
Caching class
public class Class1 {
private static Map<Integer, Integer> map = new HashMap<>();
public Class1() {
for (int i = 0; i < 20; i++) {
map.put(i, ++i);
}
}
public void reload() throws InterruptedException {
Map<Integer, Integer> exist = map;
System.out.println("are you waiting ");
System.out.println("waiting over");
map = new HashMap<>();
for (Map.Entry<Integer, Integer> entry : exist.entrySet()) {
map.put(entry.getKey(), entry.getValue());
}
for (int i = 100; i < 120; i++) {
map.put(i, ++i);
}
}
public Map<Integer, Integer> getMap() {
return map;
}
}
Class initializing the cache
public class Class2 {
private static Class1 cache = new Class1();;
public Class1 getCache() {
return cache;
}
public void reload() throws InterruptedException {
cache.reload();
}
}
class using the cache
package com.diaryreaders.corejava.algorithms.dp;
public class Class3 {
public static void main(String[] args) {
final Class2 klass = new Class2();
Runnable runn1 = new Runnable() {
#Override
public void run() {
int i = 50, j = 50;
while (i < 100) {
System.out.println("I am stuck due to lock");
klass.getCache().getMap().put(i++, j++);
System.out.println(klass.getCache().getMap());
}
}
};
Runnable runn2 = new Runnable() {
#Override
public void run() {
try {
System.out.println("Calling reloading");
klass.reload();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t1 = new Thread(runn1);
Thread t2 = new Thread(runn2);
t1.start();
t2.start();
}
}
As thread t2 is calling reloading, t1 should be blocked i.e cache put method be blocked till reloading completes
I cant seem to find the problem on the code but it the server is not displaying anything. It displays the catch. Client seems find and it sets the players name and score and sends it but I cant seem to find the issue on this one why server is not displaying the name and score.
Here is my Client:
public class Client
{
private static final int BUFSIZE = 64;
public static void main(String[] args) throws IOException
{
try
{
int scores;
Scanner in = new Scanner(System.in);
Socket clntSock = new Socket("127.0.0.1", 6000);
System.out.println("What is the filename?");
String input = in.nextLine();
Scanner fileInput = new Scanner(new File(input));
ObjectOutputStream out = new
ObjectOutputStream(clntSock.getOutputStream());
Player playerObject = new Player();
playerObject.setName(fileInput.nextLine());
System.out.println(""+playerObject.getName());
for (int i = 0; i < 5; i++)
{
scores = Integer.parseInt(fileInput.nextLine());
playerObject.setScore(scores);
System.out.println(""+playerObject.getScores().get(i));
}
out.writeObject(playerObject);
in.close();
fileInput.close();
out.close();
clntSock.close();
}
catch ( UnknownHostException ex )
{
System.out.println( "Unknown host" );
}
}
}
and my Host:
public class Host
{
private static final int BUFSIZE = 64;
public static void main(String[] args) throws IOException
{
// Step 1: Create a ServerSocket.
ServerSocket servSock = new ServerSocket(6000);
PrintStream fileOut = new PrintStream("Datafromclient.txt");
try
{
// Step 2: Wait for a connection..
Socket clntSock = servSock.accept();
// Step 3: Get input and output streams.
System.out.println("Step 3: Get object input stream.,");
ObjectInputStream objectIn = new
ObjectInputStream(clntSock.getInputStream());
Player playerObjct = (Player)objectIn.readObject();
System.out.println("The name of Player: "+playerObjct.getName());
for(int i=0; i <5; i++)
{
System.out.println("Scores:"+playerObjct.getScores().get(i));
}
objectIn.close();
clntSock.close();
// Step 5: Close connection
objectIn.close();
clntSock.close();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
System.err.println(e);
}
}
}
My player class:
public class Player
private String name;
private int playerId;
private int bestScore;
private static int numberOfPlayers = 0;
private ArrayList<Integer> scores = new ArrayList<Integer>();
/* -------------- CONSTRUCTOR --------------------------------------
*/
public Player()
{
numberOfPlayers++;
playerId = numberOfPlayers;
}
public Player(String name)
{
this.name = name;
}
//Create set method for setName
public void setName(String name)
{
this.name = name;
}
//Create set method for setScores
public void setScore(int score)
{
scores.add(score);
}
//Create get method for getPlayerId
public int getPlayerId()
{
return this.playerId;
}
//Create get method for getName
public String getName()
{
return this.name;
}
//Create get method for getScores
public ArrayList<Integer> getScores()
{
return scores;
}
//Create get method for getBestScore
public int getBestScore()
{
calculateBestScore();
return bestScore;
}
//Method to expose the value of numberOfPlayers
public static int getNumberOfPlayers()
{
return numberOfPlayers;
}
//Create get method for calcualteAverage
public double calculateAverage()
{
Integer sum = 0;
if(!scores.isEmpty())
{
for(Integer score : scores)
{
sum += score;
}
return sum.doubleValue() / scores.size();
}
return sum;
}
public void calculateBestScore()
{
bestScore = Collections.max(scores);
}
}
I was missing
import java.io.Serializable;
public class Player implements Serializable
now its working.
I am trying to implement a busy waiting mechanism, using 2 flags. I get a deadlock, but just can't understand why... it looks to me as if it should work...
sorry for the long code, That's the shortest I succeeded to make it.
package pckg1;
public class MainClass {
public static void main(String[] args) {
Buffer b = new Buffer();
Producer prod = new Producer(b);
Consumer cons = new Consumer(b);
cons.start();
prod.start();
}
}
class Producer extends Thread {
private Buffer buffer;
public Producer(Buffer buffer1) {
buffer = buffer1;
}
public void run() {
for (int i = 0; i < 60; i++) {
while (!buffer.canUpdate)
;
buffer.updateX();
buffer.canUpdate = false;
buffer.canUse = true;
}
}
}
class Consumer extends Thread {
private Buffer buffer;
public Consumer(Buffer buffer1) {
buffer = buffer1;
}
public void run() {
for (int i = 0; i < 60; i++) {
while (!buffer.canUse)
;
buffer.consumeX();
buffer.canUse = false;
buffer.canUpdate = true;
}
}
}
class Buffer {
private int x;
public boolean canUpdate;
public boolean canUse;
public Buffer() {
x = 0;
canUpdate = true;
}
public void updateX() {
x++;
System.out.println("updated to " + x);
}
public void consumeX() {
System.out.println("used " + x);
}
}
I recommend that all the logic concerning Buffer should go into that class.
Also, accessing (and modifying) the flags must be protected, if 2 or more have access to it. That's why I put synchronised to the 2 methods.
class Buffer {
private int x;
private boolean canUpdate;
private boolean canUse;
public Buffer() {
x = 0;
canUpdate = true;
}
public synchronised void updateX() {
x++;
System.out.println("updated to " + x);
canUpdate = false;
canUse = true;
}
public synchronised void consumeX() {
System.out.println("used " + x);
canUpdate = true;
canUse = false;
}
public synchronised boolean canUse() {
return canUse;
}
public synchronised boolean canUpdate() {
return canUpdate;
}
}
Also, remove the canUpdate and canUse writes from the Producer and Consumer classes, and replace the reads (in the conditons) with the methods.
Also, it would be useful to introduce some Thread.sleep(100) in the waiting loops.