Changing an arrays elements with thread - java

I need the change the elements of an array by using a thread. It should change (add or sub an integer number) an element randomly, sleep for 2 sec and change another one randomly.
So i created my array and my thread, but I don't know how to change it.
public static void main(String[] args) {
int [] myarray= new int[5];
Thread x= new Thread();
x.start();
try
{
x.sleep(2000);
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
}
}
public class myThread implements Runnable {
public myThread(){ //an empty constructor, to pass parameters
}
public void run(){
}
public void update(){ //i tohught i could use that for changing elements
}

First, you have to create an class declaration, that accepts required arr and implements run() method with logic.
public static class MyThread implements Runnable {
private final int[] arr;
private final Random random = new Random();
private MyThread(int[] arr) {
this.arr = arr;
}
#Override
public void run() {
try {
while (true) {
// wait for 2 seconds
Thread.sleep(TimeUnit.SECONDS.toMillis(2));
// randomly choose array element
int i = random.nextInt(arr.length);
// randomly choose increment or decrement an elements
boolean add = random.nextBoolean();
// lock WHOLE array for modification
synchronized (arr) {
arr[i] = add ? arr[i] + 1 : arr[i] - 1;
}
}
} catch(InterruptedException e) {
}
}
}
Second, you have to create an array and required number of threads for modifications.
// create an array
int[] arr = new int[5];
// create threads and start
for (int i = 0; i < 20; i++)
new Thread(new MyThread(arr)).start();
That's all basically. Sure, it is possible to not lock whole array to modify only one elements, but this is another story.

Related

How come a thread leave lines behind?

I'm new to programming and been studying threads for some time now.
So, the following code should give an output of:
one 98098
two 98099
and it does sometimes.
When I try to run it for a couple of times, it gives different outputs. I can understand that the JVM controls the threads and I can't directly affect it, but some of the outputs are less than 98,000 even though the for loop is adding 1000 for 98 times. How is this happening? Can a thread leave lines behind? Or did I do something wrong (note: the expected output sometimes shows on the screen, but not always)
public class TestThreads {
public static void main(String [] args) {
ThreadOne t1 = new ThreadOne();
Thread one = new Thread(t1);
ThreadTwo t2 = new ThreadTwo();
Thread two = new Thread(t2);
one.start();
two.start();
}
}
class Accum {
private int counter = 0;
private static Accum a = new Accum();
private Accum() {
}
public static Accum getAccum() {
return a;
}
public int getCount() {
return counter;
}
public void updateCounter(int add) {
counter += add;
}
}
class ThreadOne implements Runnable {
Accum a = Accum.getAccum();
public void run() {
for(int x=0; x < 98; x++) {
a.updateCounter(1000);
try {
Thread.sleep(50);
} catch(InterruptedException ex) { }
}
System.out.println("one "+a.getCount());
}
}
class ThreadTwo implements Runnable {
Accum a = Accum.getAccum();
public void run() {
for(int x=0; x < 99; x++) {
a.updateCounter(1);
try {
Thread.sleep(50);
} catch(InterruptedException ex) { }
}
System.out.println("two "+a.getCount());
}
}
Basically, your updateCounter method isn't thread-safe. If it's called from two threads at the same time, you can lose information.
Let's rewrite it to make it more obvious why that's the case:
public void updateCounter(int add) {
// Fetch
int originalValue = counter;
// Compute
int newValue = originalValue + add;
// Store
counter = newValue;
}
Imagine what happens if two threads come into the method at the same time. We'll pretend that there's some "total ordering" of what happens - the reality is more complex than that, but even the simplified form shows the problem. Suppose counter has a value of 5 to start with, and on thread x we're calling updateCounter(3) and on thread y we're calling updateCounter(4). We could imagine this sequence of events:
Thread x executes the "fetch" operation: originalValue = 5 (local variable, unaffected by thread y)
Thread y executes the "fetch" operation: originalValue = 5
Thread x executes the "compute" operation: newValue = 8
Thread y executes the "compute" operation: newValue = 9
Thread x executes the "store" operation: counter = 8 (note that newValue in thread x is separate to the one in thread y)
Thread y executes the "store" operation: counter = 9
So we end up with the value of counter being 9... as if the updateCounter(3) call had never taken place. If the last two operations happened in the reverse order, then counter would be 8 instead.
The way to fix this is to use the AtomicInteger class which is designed specifically to make operations like this atomic:
class Accum {
private final AtomicInteger counter = new AtomicInteger(0);
private static Accum a = new Accum();
private Accum() {
}
public static Accum getAccum() {
return a;
}
public int getCount() {
return counter.get();
}
public void updateCounter(int add) {
counter.addAndGet(add);
}
}

How to correctly use the Threads

I have the following task :
Create Class called: ElementsProvider(int n, List elements) that will provide N random elements into given list.
Elements Provider will be an thread.
Try create 4 instances, each of this instance will add 1000 random elements into the list.
start all instances at once and wait until they end.
print list size.
And here is what is did ,
Main:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class ElementsProvider implements Runnable{
private final List<Integer> list;
private final int n;
public ElementsProvider(List<Integer> list, int n){
this.list = list;
this.n = n;
}
#Override
public void run() {
Random random = new Random();
for (int i = 0; i < n; i++) {
list.add(random.nextInt());
}
}
public static void main(String[] args) throws InterruptedException {
List<Integer> list = new ArrayList<>();
int n = 1000;
ElementsProvider e1 = new ElementsProvider(list, n);
ElementsProvider e2 = new ElementsProvider(list, n);
ElementsProvider e3 = new ElementsProvider(list, n);
ElementsProvider e4 = new ElementsProvider(list, n);
Thread t1 = new Thread(e1);
Thread t2 = new Thread(e2);
Thread t3 = new Thread(e3);
Thread t4 = new Thread(e4);
t1.start();
t2.start();
t3.start();
t4.start();
t1.join();
t2.join();
t3.join();
t4.join();
System.out.println(list);
}
}
Apparently I got that the task is not ok.
Feedback that I got is :
wrong, try to print list size, it will be different each time You run the program.
Can someone point me where I am mistaking please?
You proposed this change in a comment on your original question, above:
#Override
public void run() {
synchronized (ElementsProvider.class) {
Random random = new Random();
for (int i = 0; i < n; i++) {
list.add(random.nextInt());
}
}
}
O.K., That will ensure that your program always prints the correct answer, but it does so by making your program effectively single-threaded. When you put the entire body of the threads' run() method in a single synchronized block, you prevent them from running concurrently. But, running concurrently is the only reason to use threads.
You need to synchronize a smaller part of the code. The only variable that the threads share is the list. There is no reason for new Random() to be inside the synchronized block, and there is no reason for random.nextInt() to be inside it. The only thing that needs to be inside the synchronized block is the list.add() call.
I'd add a static semaphore to the your ElementsProvider class:
public class ElementsProvider implements Runnable {
private final List<Integer> list;
private final int n;
private static Semaphore semaphore = new Semaphore(1);
public ElementsProvider(List<Integer> list, int n) {
this.list = list;
this.n = n;
}
#Override
public void run() {
Random random = new Random();
List<Integer> l = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
l.add(random.nextInt());
}
try {
semaphore.acquire();
System.out.println("Adding " + l.size() + " elements to list");
list.addAll(l);
} catch (Exception e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}
}

How to assign objects to an array?

So my array currently assign 5 instances of a dice object. My issue is that I have another class that needs to lock a dice from use.
public class Yahtzee {
OneDice[] dice = new OneDice[5];
public Yahtzee() {
yahtzeeRoll(); //constructor
}
public void yahtzeeRoll() {
for (int i = 0; i != dice.length; i++) {
dice[i] = new OneDice();
}
public void lock(int which) {
dice[which - 1].lockDice();
}
}
however my dice[i] = new OneDice(); creates a whole new set of random numbers each time yahtzeeRoll is called.
here is the method passing the which parameter.
#Override
public void choose() {
int which;
Scanner sc = new Scanner(System.in);
System.out.println(getName() + " Rolling.");
hand.printYahtzee();
System.out.println("Would you like to lock dice 1? 1 for yes");
choice = sc.nextInt();
if (choice == 1) {
which = 1;
hand.lock(which);
}
how can I assign a random value to each dice index without creating a brand new set of rolls that negates the lock. At least that appears to be the issue to me?
It sounds like you need to just skip over entries which are locked:
for (int i = 0; i < dice.length; i++) {
if (dice[i] == null || !dice[i].isLocked()) {
dice[i] = new OneDice();
}
}
Either that, or change your code to initialize dice in the constructor with new instances, but make your yahtzeeRoll method just change the values within the existing unlocked instances, instead of creating new instances. For example:
public Yahtzee() {
for (int i = 0; i < dice.length; i++) {
dice[i] = new OneDice();
}
rollUnlocked();
}
public void rollUnlocked() { // Renamed from yahtzeeRoll for clarity
for (OneDice die : dice) {
die.rollIfUnlocked(); // Or whatever method you want
}
}
(where rollIfUnlocked would reroll the single die, only if it hadn't previously been locked).
Don't reinitialize the entire array each time you roll. In real life when playing yahtzee you don't go grab 5 new dice every time you roll.
create OneDice as follows:
class OneDice {
int value;
boolean locked;
void roll(){
if(!locked)
value = Math.nextInt(6);
}
int getValue(){
return value;
}
void setLock(boolean lock){
locked = lock;
}
boolean isLocked(){
return locked;
}
}

How to Add Java Multithreading

At work training, I'm writing a Java (in which I have 0 experience) program that should meet the following criteria:
Write a program that replicates distributed computing application
Create central 'scheduler' object which contains a list of M random numbers
Create N processor threads that retrieve a number from the scheduler then loop that many times before requesting another number
If no numbers are available from the scheduler, wait to request another number.
If no more numbers are left, all the threads should end.
So far, I created an object with an array of random numbers, but I really don't know how to proceed with multithreading. Could someone please guide me through it? This is what I have so far, along with comments indicating pseudo code.
public class ThreadDemo extends Thread
{
//create new array of arbitrary size 5
static int SIZE = 5;
static int[] myIntArray = new int[SIZE];
public ThreadDemo()
{
start();
}
class RunnableThread implements Runnable {
Thread runner;
public RunnableThread() {
}
public RunnableThread(String threadName) {
runner = new Thread(this, threadName); // (1) Create a new thread.
System.out.println(runner.getName());
runner.start(); // (2) Start the thread.
}
public void run() {
//Display info about this particular thread
System.out.println(Thread.currentThread());
}
}
public static void main(String[] args)
{
for(int i=0; i<SIZE; i++)
{
myIntArray[i] = (int)(Math.random() * 10);
}
ThreadDemo scheduler = new ThreadDemo();
//create M processor threads that retrieve number from scheduler
//for(int i=0; i<SIZE; i++)
//
//if no threads available
//make the scheduler thread wait() ??
//if empty
//stop() the scheduler thread ??
}
}
Could anyone steer me in the right direction?
Thank you!
As a first pointer: don't start threads in a constructor and don't use the Runnable object to start a thread using itself. It's very confusing to whoever reads the code.
Here's my take on this problem (hope I didn't get carried away):
class Scheduler {
private int[] numbers;
private AtomicInteger current = new AtomicInteger();
public Scheduler(int count) {
Random rand = new Random();
numbers = new int[count];
for(int i = 0; i < count; i++) {
numbers[i] = rand.nextInt();
if(numbers[i] < 0) numbers[i] *= -1;
}
}
public int getNextNumber() {
int local = current.incrementAndGet();
if(local >= numbers.length) {
return -1;
}
return numbers[local];
}
}
First, we define the Scheduler class that holds an array of random (positive) integers and returns a number from the array on-demand, based on an atomically incrementing counter.
class Task implements Runnable {
private Scheduler scheduler;
public Task(Scheduler scheduler) {
this.scheduler = scheduler;
}
public void run() {
while(true) {
int limit = scheduler.getNextNumber(); // get next number
if(limit == -1) return; // no more numbers
System.out.println(limit);
for(int i = 0; i < limit; i++) {
// spin
}
}
}
}
The Task class holds the code that each thread executes. Each thread loops indefinitely requesting numbers from the Scheduler, until the array is exhausted.
public class Test {
public static void main(String[] args) throws InterruptedException {
Scheduler s = new Scheduler(100);
ExecutorService exec = Executors.newFixedThreadPool(4);
for(int i = 0; i < 4; i++) {
exec.submit(new Task(s));
}
exec.shutdown();
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}
In the main class we set up a thread pool and execute 4 threads to do the aforementioned tasks.
This is a good place to start. IT will also help to look at a executor service. Here is an example.
You might also want to take a look at some of the concurrent collections. It might be worth using a queue instead of an array so its a little cleaner to tell when something has been pulled out of it.
As per my understanding of your Homework, you need to create a producer and worker thread units. Please refer the below link, which will suits your requirement.
http://www.exampledepot.com/egs/java.lang/WorkQueue.html
Thanks
Thanikachalan
You might want to take a look at te ThreadPoolExecutor
You should end up with something like this.
public static void main(){
ThreadPoolExecutor tpe = new ThreadPoolExecutor(...);
List<Integer> numbers = getNumberList();
for(Integer i : numbers){
tpe.submit(new MyRunnable(i) {
Integer i;
public MyRunnable(Integer i){
this.i=i;
}
#Override
public void run() {
dosomethingWith(i);
}
}
}
}

make a thread which recieves values from other threads

This program in Java creates a list of 15 numbers and creates 3 threads to search for the maximum in a given interval. I want to create another thread that takes those 3 numbers and get the maximum. but i don't know how to get those values in the other thread.
public class apple implements Runnable{
String name;
int time, number, first, last, maximum;
int[] array = {12, 32, 54 ,64, 656, 756, 765 ,43, 34, 54,5 ,45 ,6 , 5, 65};
public apple(String s, int f, int l){
name = s;
first = f;
last = l;
maximum = array[0];
}
public void run(){
try{
for(int i = first; i < last; i++ )
{
if(maximum < array[i])
{
maximum = array[i];
}
}
System.out.println("Thread"+ name + "maximum = " + maximum);
}catch(Exception e){}
}
public static void main(String[] args){
Thread t1 = new Thread(new apple("1 ", 0, 5));
Thread t2 = new Thread(new apple("2 ", 5, 10 ));
Thread t3 = new Thread(new apple("3 ", 10, 15));
try{
t1.start();
t2.start();
t3.start();
}catch(Exception e){}
}
}
Here is how ExecutorService and ExecutorCompletionService can solve it:
public class MaxFinder {
private int[] values;
private int threadsCount;
public MaxFinder(int[] values, int threadsCount) {
this.values = values;
this.threadsCount = threadsCount;
}
public int find() throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(threadsCount);
ExecutorCompletionService<Integer> cs = new ExecutorCompletionService<Integer>(executor);
// Split the work
int perThread = values.length / threadsCount;
int from = 0;
for(int i = 0; i < threadsCount - 1; i++) {
cs.submit(new Worker(from, from + perThread));
from += perThread;
}
cs.submit(new Worker(from,values.length));
// Start collecting results as they arrive
int globalMax = values[0];
try {
for(int i = 0; i < threadsCount; i++){
int v = cs.take().get();
if (v > globalMax)
globalMax = v;
}
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
executor.shutdown();
return globalMax;
}
private class Worker implements Callable<Integer> {
private int fromIndex;
private int toIndex;
public Worker(int fromIndex, int toIndex) {
this.fromIndex = fromIndex;
this.toIndex = toIndex;
}
#Override
public Integer call() {
int max = values[0];
for(int i = fromIndex; i<toIndex; i++){
if (values[i] > max)
max = values[i];
}
return max;
}
}
}
In this solution, N threads work concurrently, each on its portion of the array. The caller thread is responsible for gathering the local maximums as they arrive, and find the global maximum. This solution uses some non-trivial concurrency tools from java.util.concurrent package.
If you prefer a solution that only uses primitive synchronization tools, then you should use a synchronized block in the worker threads, that sets the maximum in some data member and then notifies the collector thread. The collector thread should be in a loop, waiting for notification and then examining the new number, and updating the global maximum if needed. This "consumer producer" model requires careful synchronization.
Based on the code you have, the simplest solution is to join the main thread to each instance thread and then get the max value from them for comparison purposes. Like so:
int globalMax;
try{
t1.start();
t2.start();
t3.start();
t1.join();
globalMax = t1.maximum;
t2.join();
if (t2.maximum > globalMax) {
globalMax = t2.maximum;
}
t3.join();
if (t3.maximum > globalMax) {
globalMax = t3.maximum;
}
} catch(Exception e){
}
Instead of implementing Runnable, try implementing Callable, which is capable of returning a result. The tutorial given here is a good source for describing how to do this.
Another approach to your problem could be to create an object which each apple instance (not sure why you've called it this) could register its maximum with the object. This new class could be passed into each apple constructor, then the apple could call a method, passing its own maximum into this.
For instance:
public class MaximumOfMaximumsFinder implements Runnable {
private List<Integer> maximums = new ArrayList<Integer>();
public void registerSingleMaximum(Integer max) {
maximums.add(max);
}
public void run() {
// use similar logic to find the maximum
}
}
There are several issues around making sure this is coordinated with the other threads, I'll leave this to you, since there's some interesting things to think about.

Categories

Resources