1

I have a Thread that run for a long time (5-6 min).

public class ExportThread implements Runnable {
    private Integer totalExport = 0;

    @Override
    public void run() {
        try {
            exportCorner();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void exportCorner() {
        List<MyObject> list = ......
        for(MyObject o : list){
            .......
            totalExport++;
        }
    }
}

This Thread runs from another class. How can I get the totalExport again and again after a small interval ?

Mr. Mak
  • 837
  • 1
  • 11
  • 25
  • How do we usually get a value of `private` class field? what challenges you facing here? Getting the correct value or getting it periodically?Its really not clear from your question as what you tried and where you got stuck? – Sabir Khan Jun 28 '16 at 10:53

3 Answers3

3

Simply you get it by adding some getters to your thread class, as @RomanKonoval said it need to be synchronized

public class ExportThread implements Runnable {
    private Integer totalExport = 0;

    @Override
    public void run() {
        try {
            exportCorner();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void exportCorner() {
        List<Integer> list = ......
        for(Integer i : list){
            totalExport += i;
        }
    }

    public synchronized Integer getTotalExport(){
        return this.totalExport;
    }
}

From your other class you can use something like that

import java.util.*;

public class MainClass {
   public static void main(String[] args) {
       ExportThread exportThread = new ExportThread();
       Thread t = new Thread(exportThread); 
       t.start(); 

      TimerTask timerTask= new MyTimerTask(exportThread);
      Timer timer = new Timer();

      timer.scheduleAtFixedRate(tasknew,new Date(),1000);      
   }

}

Then you may need to implement your timer task

public class MyTimerTask extends TimerTask { 
    private ExportThread exportThread;
    public MyTimerTask(ExportThread exportThread){
        this.exportThread = exportThread;
    }
    @Override
    public void run() {
        System.out.println(exportThread.getTotalExports());
    }
}
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Anas EL KORCHI
  • 2,008
  • 18
  • 25
  • I don't think that concurrency is so important for this case, as you can see totalExport is just a state property which have the number of operations – Anas EL KORCHI Jun 28 '16 at 10:35
  • How from here... public class ExecutorClass { public static void main(String[] args) { Thread t = new Thread(new ExportThread()); t.start(); } } – Mr. Mak Jun 28 '16 at 10:36
  • @elkorchianas concurrency is the issue here. You need to make sure that changes done in one thread are visible in the other – Roman-Stop RU aggression in UA Jun 28 '16 at 10:40
  • @RomanKonoval I understand what you mean but the the need of this case is to get the totalExport in value periodically (like a progressbar ) why we need to make synchronization ? what you suggest may be important if we deal with some variables that their values control the behavior of the application – Anas EL KORCHI Jun 28 '16 at 10:48
  • 1
    JVM can optimize access to totalExport variable for example it can store it in CPU register and more importantly do not save updated values to RAM so other thread will see outdated value of the variable. It is you responsibility as a programmer to make JVM know that this variable may be accessed from other threads (that's one reason why volatile exists). – Roman-Stop RU aggression in UA Jun 28 '16 at 10:53
  • @RomanKonoval I did see exactly what you mean after the update of my answer +1 – Anas EL KORCHI Jun 28 '16 at 11:06
  • @M.A.Khomeni check my answer I have made some updates – Anas EL KORCHI Jun 28 '16 at 11:07
2

A lock free solution using AtomicInteger

import java.util.*;
import java.util.concurrent.atomic.*;

public class ExportThread implements Runnable {
    private AtomicInteger totalExport = new AtomicInteger(0);

    @Override
    public void run() {
        try {
            exportCorner();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void exportCorner() {
        List<MyObject> list = new ArrayList<MyObject>(10);
        list.add(new MyObject());
        list.add(new MyObject());
        for(MyObject o : list){
            totalExport.getAndIncrement();
        }
        System.out.println("total export:"+getTotalExport());
    }
    public Integer getTotalExport(){
        return totalExport.get();
    }
    public static void main(String args[]){
        ExportThread t = new ExportThread();
        new Thread(t).start();
    }
}
class MyObject {

}

output:

total export:2

Steps:

  1. Define one AtomicInteger
  2. Increment the value
  3. Provide a get() method

Related SE question:

Practical uses for AtomicInteger

Community
  • 1
  • 1
Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
-1

If I understand your problem correctly, it really looks like Observer design pattern :

Documentation : https://en.wikipedia.org/wiki/Observer_pattern

The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems. The Observer pattern is also a key part in the familiar model–view–controller (MVC) architectural pattern.[1] The observer pattern is implemented in numerous programming libraries and systems, including almost all GUI toolkits.

Mickael
  • 4,458
  • 2
  • 28
  • 40