I have Sum class, Creator class, Item class and Main. The Creator creates random Items and adds them to an ArrayList which is in the Item class. The Sum class reads items and sums the weight of all. In the Main class I start in multiple threads Creator and Sum. Both classes implement Runnable and override the run method. After 200 created are items into is printed in the console.
How to synchronize this methods? When I start threads, the method from Sum ends first and returns weight 0 and after that Creator creating 40 000 random Items. I will create items and at the same time Sum all weights of them and in the end Return how many items were created and weight of all of them.
Sum class method:
@Override
public synchronized void run() {
for(Towar x: Towar.list){
try {
Thread.currentThread().wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
counter++;
sum+=x.getWaga();
if(counter%100==0){
System.out.println("Sum of "+counter+" items");
}
}
System.out.println("Total weight of Items: "+sum);
}
Creator class method:
@Override
public void run() {
reader=new Scanner(text);
while(reader.hasNextLine()){
counter++;
String[] x=reader.nextLine().split("_");
synchronized (Towar.getList()){
Towar.add(new Towar(x[0], Integer.parseInt(x[1])));
Towar.list.notify();
if(counter%200==0){
System.out.println("Created "+counter+" items");
}
}
}
System.out.println("Created in total: "+counter+" items");
}
BlockingQueue
I would recommend using implementations of the BlockingQueue
interface, instead of ArrayList
. A BlockingQueue
is thread-safe.
To quote the Javadoc:
BlockingQueue
implementations are thread-safe. All queuing methods achieve their effects atomically using internal locks or other forms of concurrency control. However, the bulk Collection operationsaddAll
,containsAll
,retainAll
andremoveAll
are not necessarily performed atomically unless specified otherwise in an implementation. So it is possible, for example, foraddAll(c)
to fail (throwing an exception) after adding only some of the elements inc
.
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
reader=new Scanner(text);
while(reader.hasNextLine()){
counter++;
String[] x=reader.nextLine().split("_");
q.put(new Towar(x[0], Integer.parseInt(x[1])));
if(counter%200==0){
System.out.println("Created "+counter+" items");
}
}
q.put(null);
System.out.println("Created in total: "+counter+" items");
}
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
long sum = 0;
try {
while (true) {
Towar x = (Towar)queue.take();
if (x == null) return;
counter++;
sum+=x.getWaga();
if(counter%100==0){
System.out.println("Sum of "+counter+" items");
}
}
} catch (InterruptedException ex) { ... handle ...}
}
}