diff options
author | Keuin <[email protected]> | 2020-04-27 17:42:07 +0800 |
---|---|---|
committer | keuin <[email protected]> | 2020-04-27 17:42:07 +0800 |
commit | 7444c2b1f281b5b147717ba2a2ed6798c66a057b (patch) | |
tree | 8d8952b2f3aaf1e497e8667b80fc59b91536c822 /src/main/java/com/keuin/kbackupfabric/operation/abstracts | |
parent | 33857f4bc061d8dc01a6d9d10e108da7cd7c6d18 (diff) |
Refactored code for a better implementation of async and blocking task.
Diffstat (limited to 'src/main/java/com/keuin/kbackupfabric/operation/abstracts')
10 files changed, 290 insertions, 0 deletions
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/abstracts/AbstractAsyncOperation.java b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/AbstractAsyncOperation.java new file mode 100644 index 0000000..f1a19de --- /dev/null +++ b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/AbstractAsyncOperation.java @@ -0,0 +1,53 @@ +package com.keuin.kbackupfabric.operation.abstracts; + +public abstract class AbstractAsyncOperation extends AbstractSerializedOperation { + + private final Thread thread; + private final String name; + private final Object sync = new Object(); + + protected AbstractAsyncOperation(String name) { + this.name = name; + this.thread = new Thread(this::async, name); + } + + /** + * Start the worker thread. + * + * @return true if succeed starting, false if already started. + */ + @Override + protected final boolean operate() { + synchronized (sync) { + if (thread.isAlive()) + return false; + if (!sync()) + return false; + thread.start(); + return true; + } + } + + /** + * Implement your async operation here. + * When this method returns, the operation must finish. + */ + protected abstract void async(); + + /** + * If necessary, implement your sync operations here. + * It will be invoked before starting the async thread. + */ + protected boolean sync() { + return true; + } + + public final String getName() { + return name; + } + + @Override + public String toString() { + return "operation " + name; + } +} diff --git a/src/main/java/com/keuin/kbackupfabric/operation/abstracts/AbstractBlockingOperation.java b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/AbstractBlockingOperation.java new file mode 100644 index 0000000..de672cd --- /dev/null +++ b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/AbstractBlockingOperation.java @@ -0,0 +1,58 @@ +package com.keuin.kbackupfabric.operation.abstracts; + +import com.keuin.kbackupfabric.operation.abstracts.i.Blocking; + +public abstract class AbstractBlockingOperation extends AbstractSerializedOperation implements Blocking { + + private static final Object sync = new Object(); + private static boolean isBlocking = false; + private boolean wasBlocked = false; + private boolean noUnblocking = false; + + @Override + protected final boolean operate() { + synchronized (sync) { + if (isBlocking) { + System.out.println("blocked."); + wasBlocked = true; + return false; + } else { + System.out.println("not blocked."); + wasBlocked = false; + isBlocking = true; + } + } + boolean exitCode = blockingContext(); + if (!noUnblocking) + isBlocking = false; + return exitCode; + } + + public final boolean isBlocked() { + return wasBlocked; + } + + protected final void block(boolean blockState) { + isBlocking = blockState; + } + + protected void noUnblocking(boolean b) { + noUnblocking = b; + } + + protected boolean blockAndGet() { + synchronized (sync) { + boolean b = isBlocking; + isBlocking = true; + return b; + } + } + + /** + * Implement your blocked operation here. + * + * @return the stat code. + */ + protected abstract boolean blockingContext(); + +} diff --git a/src/main/java/com/keuin/kbackupfabric/operation/abstracts/AbstractConfirmableOperation.java b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/AbstractConfirmableOperation.java new file mode 100644 index 0000000..0a56008 --- /dev/null +++ b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/AbstractConfirmableOperation.java @@ -0,0 +1,11 @@ +package com.keuin.kbackupfabric.operation.abstracts; + +public abstract class AbstractConfirmableOperation extends AbstractSerializedOperation { + + public final boolean confirm() { + return operate(); + } + + @Override + public abstract String toString(); +} diff --git a/src/main/java/com/keuin/kbackupfabric/operation/abstracts/AbstractSerializedOperation.java b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/AbstractSerializedOperation.java new file mode 100644 index 0000000..3168e8c --- /dev/null +++ b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/AbstractSerializedOperation.java @@ -0,0 +1,12 @@ +package com.keuin.kbackupfabric.operation.abstracts; + +public abstract class AbstractSerializedOperation { + /** + * Do your operation here. + * This method is not designed to be public. + * When this method returns, the operation must have finished. + * + * @return the stat code. + */ + protected abstract boolean operate(); +} diff --git a/src/main/java/com/keuin/kbackupfabric/operation/abstracts/InvokableAsyncBlockingOperation.java b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/InvokableAsyncBlockingOperation.java new file mode 100644 index 0000000..6268d5a --- /dev/null +++ b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/InvokableAsyncBlockingOperation.java @@ -0,0 +1,66 @@ +package com.keuin.kbackupfabric.operation.abstracts; + +import com.keuin.kbackupfabric.operation.abstracts.i.Blocking; +import com.keuin.kbackupfabric.operation.abstracts.i.Invokable; + +public abstract class InvokableAsyncBlockingOperation implements Invokable, Blocking { + + private final InvokableAsyncOperation asyncOperation; + private final HackedBlockingOperation blockingOperation; + + public InvokableAsyncBlockingOperation(String name) { + asyncOperation = new InvokableAsyncOperation(name) { + @Override + protected void async() { + InvokableAsyncBlockingOperation.this.async(); + // When the async operation finishes, unblock + blockingOperation.noUnblocking(false); + blockingOperation.block(false); + } + + @Override + protected boolean sync() { + return InvokableAsyncBlockingOperation.this.sync(); + } + }; + + blockingOperation = new HackedBlockingOperation(); + } + + @Override + public boolean invoke() { + return blockingOperation.invoke(); + } + + @Override + public boolean isBlocked() { + return blockingOperation.isBlocked(); + } + + protected abstract void async(); + + protected boolean sync() { + return true; + } + + private class HackedBlockingOperation extends InvokableBlockingOperation { + + @Override + protected boolean blockingContext() { + + noUnblocking(true); + return asyncOperation.invoke(); + } + + @Override + public void noUnblocking(boolean b) { + super.noUnblocking(b); + } + + @Override + public void block(boolean blockState) { + super.block(blockState); + } + } + +} diff --git a/src/main/java/com/keuin/kbackupfabric/operation/abstracts/InvokableAsyncOperation.java b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/InvokableAsyncOperation.java new file mode 100644 index 0000000..518f670 --- /dev/null +++ b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/InvokableAsyncOperation.java @@ -0,0 +1,32 @@ +package com.keuin.kbackupfabric.operation.abstracts; + +public abstract class InvokableAsyncOperation extends InvokableOperation { + + private final AbstractAsyncOperation asyncOperation; + + + public InvokableAsyncOperation(String name) { + asyncOperation = new AbstractAsyncOperation(name) { + @Override + protected void async() { + InvokableAsyncOperation.this.async(); + } + + @Override + protected boolean sync() { + return InvokableAsyncOperation.this.sync(); + } + }; + } + + protected abstract void async(); + + protected boolean sync() { + return true; + } + + @Override + protected boolean operate() { + return asyncOperation.operate(); + } +} diff --git a/src/main/java/com/keuin/kbackupfabric/operation/abstracts/InvokableBlockingOperation.java b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/InvokableBlockingOperation.java new file mode 100644 index 0000000..b1a3748 --- /dev/null +++ b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/InvokableBlockingOperation.java @@ -0,0 +1,39 @@ +package com.keuin.kbackupfabric.operation.abstracts; + +import com.keuin.kbackupfabric.operation.abstracts.i.Blocking; + +public abstract class InvokableBlockingOperation extends InvokableOperation implements Blocking { + + private final AbstractBlockingOperation operation = new AbstractBlockingOperation() { + @Override + protected boolean blockingContext() { + return InvokableBlockingOperation.this.blockingContext(); + } + }; + + @Override + protected final boolean operate() { + return operation.operate(); + } + + /** + * Implement your blocked operation here. + * + * @return stat code. + */ + protected abstract boolean blockingContext(); + + protected void block(boolean blockState) { + operation.block(blockState); + } + + protected void noUnblocking(boolean b) { + operation.noUnblocking(b); + } + + @Override + public final boolean isBlocked() { + return operation.isBlocked(); + } + +} diff --git a/src/main/java/com/keuin/kbackupfabric/operation/abstracts/InvokableOperation.java b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/InvokableOperation.java new file mode 100644 index 0000000..47c1ca8 --- /dev/null +++ b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/InvokableOperation.java @@ -0,0 +1,9 @@ +package com.keuin.kbackupfabric.operation.abstracts; + +import com.keuin.kbackupfabric.operation.abstracts.i.Invokable; + +public abstract class InvokableOperation extends AbstractSerializedOperation implements Invokable { + public boolean invoke() { + return operate(); + } +} diff --git a/src/main/java/com/keuin/kbackupfabric/operation/abstracts/i/Blocking.java b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/i/Blocking.java new file mode 100644 index 0000000..ba1b003 --- /dev/null +++ b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/i/Blocking.java @@ -0,0 +1,5 @@ +package com.keuin.kbackupfabric.operation.abstracts.i; + +public interface Blocking { + boolean isBlocked(); +} diff --git a/src/main/java/com/keuin/kbackupfabric/operation/abstracts/i/Invokable.java b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/i/Invokable.java new file mode 100644 index 0000000..74051e3 --- /dev/null +++ b/src/main/java/com/keuin/kbackupfabric/operation/abstracts/i/Invokable.java @@ -0,0 +1,5 @@ +package com.keuin.kbackupfabric.operation.abstracts.i; + +public interface Invokable { + boolean invoke(); +} |