Simple Java multithreading test not working

I wrote some Java code that would increase the value as much as possible after 1 second using a while loop.

Then I tried to increase the four values ​​as much as I could in one second using 4 threads. I expected that with four threads I get four times the value compared to a simple loop.

The code is as follows:

package threadTest;

public class ThreadTestMain {

public static void main(String[] args) {

    long end_time = 0;
    long value = 0;
    long runtime = 0;

    long start_time = System.currentTimeMillis();
    while (runtime<=1000) {
        value++;
        runtime = System.currentTimeMillis() - start_time;
    }

    System.out.println(value);
    end_time = System.currentTimeMillis();
    System.out.println("DEBUG-> Time should be 1sec : " + (end_time - start_time));

    SeperateExecution myObject = new SeperateExecution(0);
    SeperateExecution myObject2 = new SeperateExecution(0);
    SeperateExecution myObject3 = new SeperateExecution(0);
    SeperateExecution myObject4 = new SeperateExecution(0);

    Thread worker1 = new Thread(myObject,"worker1");
    Thread worker2 = new Thread(myObject2,"worker2");
    Thread worker3 = new Thread(myObject3,"worker3");
    Thread worker4 = new Thread(myObject4,"worker4");

    worker1.start();worker2.start();worker3.start();worker4.start();
}

}

and

package threadTest;

//import java.util.concurrent.atomic.AtomicLong;

public class SeperateExecution implements Runnable {
private long value = 0;
//private AtomicLong value = null;
private long start_time = 0;

public SeperateExecution (long p_val)
{
    this.value = p_val;
    //this.value = new AtomicLong(p_val);
    //this.start_time = p_st;
}

@Override
public void run(){
    long runtime = 0;
    this.start_time = System.currentTimeMillis();
    while (runtime<=1000) {
        //value.incrementAndGet();
        value++;
        runtime = System.currentTimeMillis() - start_time;
    }
    System.out.println(Thread.currentThread().getName() + " DONE " + value + 
            " Thread Exection Time " + (System.currentTimeMillis()- start_time));
}
}

The code output is as follows:

52266551
DEBUG-> Time should be 1sec : 1001
worker1 DONE 13364059 Thread Exection Time 1001
worker2 DONE 13744972 Thread Exection Time 1001
worker4 DONE 11652084 Thread Exection Time 1001
worker3 DONE 13605645 Thread Exection Time 1001

Can someone please help me understand why multi-threaded values ​​add up with a value less than a regular while loop?

An analogy to help understand my question: if one worker can dig one hole per day, then harsh four workers can dig four holes in a day.

thank

+4
4

, : System.currentTimeMillis - , ( , ).

, , , .

: System.currentTimeMillis ? , src/os/<os>/vm/os_<os>.cpp, <os> - linux, windows solaris. , , jdk9 dev :

jlong os::javaTimeMillis() {
    FILETIME wt;
    GetSystemTimeAsFileTime(&wt);
    return windows_to_java_time(wt);
}

Java , GetSystemTimeAsFileTime . , - , , . 8 , .

, , Linux .

+3

-, .

  • 4 , java-. (, , .)

  • System.currentMill

Thread3 Value :413907923
Thread1 Value :431271274
Thread2 Value :426025618
Thread4 Value :431386076

8 ( 4 )

Thread7 Value :441240435
Thread4 Value :283265150
Thread2 Value :427759029
Thread3 Value :441240435
Thread8 Value :283265150
Thread6 Value :427759029
Thread5 Value :450884067
Thread1 Value :450884067

( SOP )

public class SimpleTask implements Runnable {
    private long value = 0;
    private volatile static int oneSecondCompleted = 0;

    public SimpleTask(long lValue) {
        this.value = lValue;
    }
    @Override
    public void run() {
        while(oneSecondCompleted <= 1){
            if (oneSecondCompleted == 1){
                while (oneSecondCompleted == 1){
                    this.value++;
                }
            }
        }
        System.out.println(Thread.currentThread().getName() +" Value :"+value);
    }

    public static void main(String args[]){

        SimpleTask task1 = new SimpleTask(0);
        SimpleTask task2 = new SimpleTask(0);
        SimpleTask task3 = new SimpleTask(0);
        SimpleTask task4 = new SimpleTask(0);

        Thread thread1 = new Thread(task1,"Thread1");
        Thread thread2 = new Thread(task2,"Thread2");
        Thread thread3 = new Thread(task3,"Thread3");
        Thread thread4 = new Thread(task4,"Thread4");

        thread1.start();thread2.start();thread3.start();thread4.start();

        oneSecondCompleted = 1;
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        oneSecondCompleted = 2;
    }
}
+1

, : SeparateExecution , , , , , ?

, SeparateExecution, , , , . , SeparateExecution, , , , start(), . .


: . , , , ( ), -var. , , 1,5 x , , .

public class Threadly {
    public static void main(String[] args) throws InterruptedException {
        doLocalVar();
        doInMainThread();
        doMultiThreaded();
    }

    private static void doLocalVar() {
        long count = 0L;
        long startTime = System.currentTimeMillis();
        long endTime = startTime;
        while (endTime - startTime < 1000L) {
            count += 1L;
            endTime = System.currentTimeMillis();
        }
        System.out.println("local: elapsed=" + (endTime - startTime) + ", count=" + count);
    }

    private static void doInMainThread() {
        Spinner spinner = new Spinner("main");
        spinner.run();
        spinner.show();
    }

    private static void doMultiThreaded() throws InterruptedException {
        int numThreads = Runtime.getRuntime().availableProcessors();
        Thread[] threads = new Thread[numThreads];
        Spinner[] spinners = new Spinner[numThreads];
        for (int i=0 ; i<numThreads ; i++) {
            spinners[i] = new Spinner("t-" + Integer.toString(i));
            threads[i] = new Thread(spinners[i]);
        }
        for (Thread thread : threads)
            thread.start();
        for (Thread thread : threads)
            thread.join();
        for (Spinner spinner : spinners)
            spinner.show();
    }

    private static class Spinner implements Runnable {
        private long startTime;
        private long endTime;
        private long count;
        private final String name;

        Spinner(String name) {
            this.name = name;
        }

        // @Override
        public void run() {
            count = 0L;
            startTime = System.currentTimeMillis();
            endTime = startTime;
            while (endTime - startTime < 1000L) {
                count += 1L;
                endTime = System.currentTimeMillis();
            }
        }

        void show() {
            System.out.println(name + ": elapsed=" + (endTime - startTime) + ", count=" + count);
        }
    }
}
0

, ​​ . . - . , , System.currenttime(), . .

while, . , System.current .

0

Source: https://habr.com/ru/post/1543472/


All Articles