Methods for accessing Shared objects and data in Java multithreaded programming

  • 2020-04-01 03:50:24
  • OfStack

There are two ways in which multiple threads can access Shared objects and data:
1. Each thread executes the same code, for example, selling tickets: multiple Windows sell 100 tickets at the same time, and the 100 tickets need to be Shared by multiple threads.
2. The code executed by each thread is different. For example, four threads are designed, in which two threads increase 1 to j each time, and the other two threads decrease 1 to j each time.

A. If each thread executes the same code, you can use the same Runnable object, which contains Shared data. This can be done by selling tickets. Each window is doing the selling task, and the selling ticket is the same data (click to see the specific case).

B. If the code executed by each thread is different, different Runnable objects need to be used. There are two ways to realize the data sharing between Runnable objects:
1) encapsulate the Shared data into an object separately, and provide methods to operate the Shared data in the object, which can facilitate mutual exclusion and communication of the operations of the Shared data.
2) take each Runnable object as the inner class of a class, share data as the member variable of the outer class, and provide the operation method of Shared data in the outer class for mutual exclusion and communication. The Runnable object of the inner class can call the method of operating Shared data in the outer class.


package com.ljq.test.thread;
 

public class MultiThreadShareData {
  private static ShareData data1 = new ShareData();
 
  public static void main(String[] args) {
    ShareData data2 = new ShareData();
    new Thread(new DecrementRunnable(data2)).start();
    new Thread(new IncrementRunnable(data2)).start();
 
    final ShareData data1 = new ShareData();
    new Thread(new Runnable() {
      @Override
      public void run() {
        data1.decrement();
 
      }
    }).start();
    new Thread(new Runnable() {
      @Override
      public void run() {
        data1.increment();
 
      }
    }).start();
 
  }
 
}
 

class DecrementRunnable implements Runnable {
  private ShareData data;
 
  public DecrementRunnable(ShareData data) {
    this.data = data;
  }
 
  public void run() {
    for(int i=0; i<100; i++){
      data.decrement();
    }
     
  }
}
 

class IncrementRunnable implements Runnable {
  private ShareData data;
 
  public IncrementRunnable(ShareData data) {
    this.data = data;
  }
 
  public void run() {
    for(int i=0; i<100; i++){
      data.increment();
    }
     
  }
}
 

class ShareData {
  private int j = 0;
 
  
  public synchronized void increment() {
    j++;
    System.out.println("j++="+j);
  }
 
  
  public synchronized void decrement() {
    j--;
    System.out.println("j--="+j);
  }
   
   
}

Note: sections of code to synchronize mutexes are best placed in separate methods, which are then placed in the same class, making it easier to synchronize mutexes and communicate between them.


Related articles: