0

I want to Synchronize functionB. I mean, when some Attriute object call functionA, there are always just run one of object's functionB in the same time. But functionC and functionD in each object can do it after functionB finished by themselves.

I tried to add synchronized in function B, but it seems like not work.

This is Attribute class:

public class Attribute {
    private String name;

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

    public void functionA() {
        synchronized (this) {
            functionB();
        }
        functionC();
        functionD();
    }

    private void functionB() {
        for (int i = 0; i < 5; i++) {
            System.out.println(name + " " + i + " time functionB.");
        }
    }

    private void functionC() {
        for (int i = 0; i < 5; i++) {
            System.out.println(name + " " + i + " time functionC.");
        }
    }

    private void functionD() {
        for (int i = 0; i < 5; i++) {
            System.out.println(name + " " + i + " time functionD.");
        }
    }
    
    public static void main(String[] args) throws IOException {    
        ArrayList<Attribute> attributes = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
             attributes.add(new Attribute("No." + i));
        }
        attributes.parallelStream().forEach(Attribute::functionA);
    }
}

After execute above code, the console show:

No.3 0 time functionB.
No.4 0 time functionB.
No.2 0 time functionB.
No.2 1 time functionB.
No.2 2 time functionB.
No.1 0 time functionB.
No.1 1 time functionB.
...

But I expect it:

No.3 0 time functionB.
No.3 1 time functionB.
No.3 2 time functionB.
No.3 3 time functionB.
No.3 4 time functionB.
No.1 0 time functionB.
No.1 1 time functionB.
No.1 2 time functionB.
No.1 3 time functionB.
No.1 4 time functionB.
No.4 0 time functionB.
No.4 1 time functionB.
...
No.1 1 time functionD.
No.3 3 time functionC.
No.2 3 time functionD.
No.1 2 time functionD.
No.4 2 time functionC.
hua
  • 169
  • 9
  • 1
    I'm not sure what you're after here. The synchronization is unnecessary. The parallel stream you have will _not_ result in multiple threads calling `functionA` on the same `Attribute` _instance_ at the same time. Each `functionA` call happens in its own thread. – Slaw May 23 '22 at 09:24
  • @Slaw In my truly code, functionB is send data to client using socket, so when different Attribute call functionB, it will upset my data sequence in socket. – hua May 23 '22 at 09:40
  • 1
    If you have to send data serially, then why execute the code in parallel? – Slaw May 23 '22 at 09:55
  • @Slaw I think it can speedup my code except functionB. – hua May 23 '22 at 10:41

1 Answers1

0

Can you use ExecutorService like below.

ExecutorService executorService = Executors.newFixedThreadPool(10);

    public void functionA() {
        synchronized (this) {
            functionB();
        }
        executorService.submit(this::functionC);
        executorService.submit(this::functionD);
    }

Not exactly elegant, but it will interleave between C and D after B is completed.

fauzimh
  • 594
  • 4
  • 16
  • It doesn't work, the execute result is same with mine. – hua May 23 '22 at 10:44
  • In my output. C and D are interleaved. Have you run it multiple times? How many processors do you have? – fauzimh May 24 '22 at 00:37
  • Not about funC and funD, it is about funB. funB in each Attribute can't do it whole code before another run funB – hua May 24 '22 at 02:16
  • If first thread is No.2, I wish it doing funB print 0 to 4 and it is continuous. Not when it run to No.2 and 2nd time, next line show No.4 1st time. – hua May 24 '22 at 02:20