Package org.squirrelframework.foundation.fsm.threadsafe

Source Code of org.squirrelframework.foundation.fsm.threadsafe.DeadLockTest

package org.squirrelframework.foundation.fsm.threadsafe;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import junit.framework.Assert;

import org.junit.Test;
import org.squirrelframework.foundation.fsm.AnonymousAction;
import org.squirrelframework.foundation.fsm.StateMachineBuilderFactory;
import org.squirrelframework.foundation.fsm.UntypedStateMachine;
import org.squirrelframework.foundation.fsm.UntypedStateMachineBuilder;

public class DeadLockTest {
   
    private UntypedStateMachine[] getTestingFSMInstances() {
        UntypedStateMachineBuilder builder1 = StateMachineBuilderFactory.create(ConcurrentSimpleStateMachine.class);
        builder1.transition().from("A").to("B").on("FIRST").perform(
                new AnonymousAction<UntypedStateMachine, Object, Object, Object>() {
            @Override
            public void execute(Object from, Object to, Object event,
                    Object context, UntypedStateMachine stateMachine) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                UntypedStateMachine fsm2 = (UntypedStateMachine)context;
                System.out.println("fsm2 current state: "+fsm2.getCurrentState());
            }
        });
       
        UntypedStateMachineBuilder builder2 = StateMachineBuilderFactory.create(ConcurrentSimpleStateMachine.class);
        builder2.transition().from("C").to("D").on("SECOND").perform(
                new AnonymousAction<UntypedStateMachine, Object, Object, Object>() {
            @Override
            public void execute(Object from, Object to, Object event,
                    Object context, UntypedStateMachine stateMachine) {
                UntypedStateMachine fsm1 = (UntypedStateMachine)context;
                System.out.println("fsm1 current state: "+fsm1.getCurrentState());
            }
        });
       
        final UntypedStateMachine fsm1 = builder1.newStateMachine("A");
        fsm1.start();
        final UntypedStateMachine fsm2 = builder2.newStateMachine("C");
        fsm2.start();
       
        return new UntypedStateMachine[]{fsm1, fsm2};
    }
   
    @Test
    public void testDeadLockProblem() {
        final UntypedStateMachine[] fsm = getTestingFSMInstances();
        final CountDownLatch eventCondition = new CountDownLatch(2);
        new Thread(new Runnable() {
            @Override
            public void run() {
                fsm[0].fire("FIRST", fsm[1]);
                eventCondition.countDown();
            }
        }, "Test-Thread-1").start();
       
        new Thread(new Runnable() {
            @Override
            public void run() {
                fsm[1].fire("SECOND", fsm[0]);
                eventCondition.countDown();
            }
        }, "Test-Thread-2").start();
       
        try {
            boolean isJobDone = eventCondition.await(1000, TimeUnit.MILLISECONDS);
            Assert.assertTrue(isJobDone==false); // due to dead lock, job cannot be done properly
        } catch (InterruptedException e) {
        }
    }
   
    @Test(timeout=100)
    public void testDeadLockFixed() {
        final UntypedStateMachine[] fsm = getTestingFSMInstances();
        final CountDownLatch eventCondition = new CountDownLatch(2);
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (fsm[0]) {
                    synchronized (fsm[1]) {
                        fsm[0].fire("FIRST", fsm[1]);
                    }
                }
                eventCondition.countDown();
            }
        }, "Test-Thread-1").start();
       
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (fsm[0]) {
                    synchronized (fsm[1]) {
                        fsm[1].fire("SECOND", fsm[0]);
                    }
                }
                eventCondition.countDown();
            }
        }, "Test-Thread-2").start();
       
        try {
            boolean isJobDone = eventCondition.await(50, TimeUnit.MILLISECONDS);
            Assert.assertTrue(isJobDone);
        } catch (InterruptedException e) {
        }
    }

}
TOP

Related Classes of org.squirrelframework.foundation.fsm.threadsafe.DeadLockTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.