Failed to sync process using Thread

I tested my skills compared to Thread. When I implemented the interface Runnableand synchronizedthe run method, I got an absolute result. But, expanding the class Thread, the result was unpredictable. The following are two cases. I think that threads in both cases use the same resource.

case 1 Runnable

class Counter{
    int count;
    public void doCount(){
        count=count+1;
    }
    public int getCount(){
        return count;
    }
}
public class One implements Runnable{
    Counter counter = new Counter(); // common object to be shared with two threads
    public void run(){
        synchronized (this) {
            for(int i=0;i<10000;i++){
                counter.doCount();
            }   
        }
    }
    public static void main(String[] args) throws InterruptedException {
        One one = new One();
        Thread t1 = new Thread(one);// using same resource 'one'
        Thread t2 = new Thread(one);// using same resource 'one'
        t1.start();
        t2.start();
        Thread.sleep(2000); // to give both threads time to complete
        System.out.println(one.counter.getCount());
    }
}

case 2 Thread

class Counter{
    int count;
    public void doCount(){
        count=count+1;
    }
    public int getCount(){
        return count;
    }
}
public class One extends Thread{
    Counter counter; //common object to be shared with two threads
    One(Counter counter){
        this.counter = counter; 
    }
    public void run(){
        synchronized (this) {
            for(int i=0;i<10000;i++){
                counter.doCount();
            }   
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        One o1 = new One(counter);// using same resource counter
        One o2 = new One(counter);// using same resource counter
        o1.start();
        o2.start();
        Thread.sleep(2000); // to give both threads time to complete
        System.out.println(counter.getCount());
    }
}

for case 1, I get 20,000 output every time. but for case 2, I get random values ​​every time. Why is this so? case 2 also uses the same resource among two threads, then why they stop receiving synchronized. can someone explain this .. I go nuts !!

+4
source share
5 answers

synchronized (this) . 2 : o1 02. synchronized (counter) , .

, , .

class Counter{
    final Object lock= new Object();
    int count;
    public void doCount(){
        synchronized (lock){
            count=count+1;
        }
    }
    public int getCount(){
        synchronized (lock) {
            return count;
        }
    }
}

, sleep, Thread.join()

+1

, Counter, . Counter , , .

, :

public class Counter {
    int count;
    public void doCount() {
        count=count+1;
    }
    public int getCount() {
        return count;
    }
}

public class CountRunner implements Runnable {
    Counter counter; 
    public CountRunner(Counter counter){
        this.counter = counter; 
    }
    public void run() {
        synchronized (counter) {
            for(int i=0;i<10000;i++){
                counter.doCount();
            }   
        }
    }
}

public class CountThread extends Thread {
    Counter counter; 
    public CountThread(Counter counter){
        this.counter = counter; 
    }
    public void run() {
        synchronized (counter) {
            for(int i=0;i<10000;i++){
                counter.doCount();
            }   
        }
    }
}

public class App {
    public static void main(String[] args) throws InterruptedException {
        countRunnerTest();
        countThreadTest();
    }

    public static void countRunnerTest() {
        Counter counter = new Counter();
        CountRunner countRunner = new CountRunner(counter);
        Thread t1 = new Thread(countRunner);
        Thread t2 = new Thread(countRunner);
        t1.start();
        t2.start();
        Thread.sleep(2000); 
        System.out.printf("CountRunnerTest result=%s", counter.getCount());
    }

    public static void countThreadTest() {
        Counter counter = new Counter();
        CountThread t1 = new CountThread(counter);
        CountThread t2 = new CountThread(counter);
        t1.start();
        t2.start();
        Thread.sleep(2000);
        System.out.printf("CountThread  result=%s", counter.getCount());
    }

}
+2

"this" i.e, o1 o2. for , , , .

ConcurrentModificationException .

+1

synchronized (this) , .

One one = new One();

, , .

2 , lock.You , .

 One o1 = new One(counter);// using same resource counter
 One o2 = new One(counter);
+1

, runnable . this .

In any case, check thisinside the synchronized function. In the first case, it is connected with One one = new One(One)... And the second One one = new One(One)It is connected with itself. Both are synchronized, but the first is synchronized with the first instance of one. However, the second is synchronized with the second instance of one. Try using a lock. It should work.

+1
source

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


All Articles