Add java docs to the code and adding some same code
This commit is contained in:
Родитель
6d25cb14cd
Коммит
0e0dbc7c26
|
@ -0,0 +1,89 @@
|
|||
package com.microsoft.sample.custom;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.microsoft.snippet.ExecutionContext;
|
||||
import com.microsoft.snippet.Snippet;
|
||||
import com.microsoft.snippet.token.ExtendableLogToken;
|
||||
import com.microsoft.snippet.token.ILogToken;
|
||||
|
||||
/**
|
||||
* Demo for showing custom implementation of Execution Path. This path, takes the data that is
|
||||
* captured from the MeasuredExecutionPath and passes it to FileExecutionPath and then the data
|
||||
* is written to the file.
|
||||
* <p>
|
||||
* We need to override LogToken also, as for the code that is non contiguous all the measurements
|
||||
* are inside the log token that is handed over to the user by Snippet.startCapture() API
|
||||
* So if we want that our new execution to work for both kinds of APIs that ie.
|
||||
* The one passed through a lambda in Snippet.capture(lambda) and Snippet.startCapture()/LogToken.endCapture()
|
||||
* We need to override both the classes.
|
||||
*/
|
||||
|
||||
public class FileExecutionPath extends Snippet.MeasuredExecutionPath {
|
||||
|
||||
@Override
|
||||
public ILogToken startCapture(String tag) {
|
||||
return super.startCapture(tag);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ExecutionContext capture(String message, Snippet.Closure closure) {
|
||||
ExecutionContext context = super.capture(message, closure);
|
||||
Log.d("Snippet", "Class: " + context.getClassName() + "Duration: " + context.getExecutionDuration());
|
||||
// Context has all the information that measured path has captured. Use that to write to files.
|
||||
return writeToFile(context);
|
||||
}
|
||||
|
||||
private ExecutionContext writeToFile(ExecutionContext context) {
|
||||
// Code to write to a file goes here, create a thread and write.
|
||||
// Finally return a the execution context(could be the same or a new implementation) with some
|
||||
// of the details that you captured.
|
||||
|
||||
// NOTE: always put the relevant information on the context before you start doing IO
|
||||
// so that the execution path could return successfully.
|
||||
return context;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ExecutionContext capture(Snippet.Closure closure) {
|
||||
return super.capture(closure);
|
||||
}
|
||||
|
||||
// We need to return a log token implementation that writes to a file when we call endCapture()
|
||||
// APIs.
|
||||
// USE ExtendableLogToken for the above purpose
|
||||
@Override
|
||||
public ILogToken startCapture() {
|
||||
return new ExtendableLogToken(super.startCapture());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILogToken find(String tag) {
|
||||
return super.find(tag);
|
||||
}
|
||||
|
||||
public class FileWritingLogToken extends ExtendableLogToken {
|
||||
|
||||
public FileWritingLogToken(ILogToken logToken) {
|
||||
super(logToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionContext endCapture(String message) {
|
||||
ExecutionContext context = super.endCapture(message);
|
||||
writeToFile(context);
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionContext endCapture() {
|
||||
ExecutionContext context = super.endCapture();
|
||||
writeToFile(context);
|
||||
return context;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
package com.microsoft.snippet;
|
||||
|
||||
/**
|
||||
* POJO Alert!
|
||||
* Wraps all the information that can be returned through the library.
|
||||
* If any other information is needed it can be added ad-hoc.
|
||||
* Custom implementation of {@link ExecutionPath} might/might not have to extend this to
|
||||
* accommodate any additional information.
|
||||
*/
|
||||
public class ExecutionContext {
|
||||
private String mClass;
|
||||
|
|
|
@ -7,6 +7,7 @@ package com.microsoft.snippet;
|
|||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RestrictTo;
|
||||
|
||||
import com.microsoft.snippet.token.ILogToken;
|
||||
import com.microsoft.snippet.token.LogTokenState;
|
||||
|
@ -17,7 +18,10 @@ import java.util.List;
|
|||
|
||||
/**
|
||||
* LogToken Pool is helps recycling the log token objects that are used by Snippet.
|
||||
* Currently there is no upper cap on the no of tokens it could hold. But we are trying to understand
|
||||
* what could be the upper limit.
|
||||
*/
|
||||
@RestrictTo(RestrictTo.Scope.LIBRARY)
|
||||
public final class LogTokenPool {
|
||||
private static final String TAG = LogTokenPool.class.getSimpleName();
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ package com.microsoft.snippet;
|
|||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.RestrictTo;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
|
@ -18,6 +20,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
* @param <T>
|
||||
* @author vishalratna
|
||||
*/
|
||||
@RestrictTo(RestrictTo.Scope.LIBRARY)
|
||||
public final class OneShot<T> {
|
||||
private static final String TAG = OneShot.class.getSimpleName();
|
||||
|
||||
|
|
|
@ -4,11 +4,14 @@
|
|||
|
||||
package com.microsoft.snippet;
|
||||
|
||||
import androidx.annotation.RestrictTo;
|
||||
|
||||
/**
|
||||
* Represents a Pair of objects
|
||||
* @param <A> A
|
||||
* @param <B> B
|
||||
*/
|
||||
@RestrictTo(RestrictTo.Scope.LIBRARY)
|
||||
public final class Pair<A, B> {
|
||||
A a;
|
||||
B b;
|
||||
|
|
|
@ -12,6 +12,7 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.microsoft.snippet.token.AttenuatedLogToken;
|
||||
import com.microsoft.snippet.token.ExtendableLogToken;
|
||||
import com.microsoft.snippet.token.ILogToken;
|
||||
import com.microsoft.snippet.token.LogTokenState;
|
||||
|
||||
|
@ -27,12 +28,21 @@ import java.util.Locale;
|
|||
* printing the logs. The work is tedious and it becomes a nightmare when we have to do it across the
|
||||
* code base. The API provided by this library could be used to monitor PRs in the PR reviews where
|
||||
* the reviewer could ask for numbers for a specific snippet and compare the before and after numbers.
|
||||
* It could also be used as a general library to print code execution duration.
|
||||
* <p>
|
||||
* The important thing to note is we can configure the code in such a way that we do not have to
|
||||
* care about the additional verbosity in the release builds as it automatically makes the code
|
||||
* no-op in the release builds or any other builds if we want. We also have an option to configure the library
|
||||
* differently in different builds. Please check {@link Snippet#install(ExecutionPath)} API.
|
||||
*
|
||||
* <h2> There are 2 ways to measure time in Snippet</h2>
|
||||
* <ol>
|
||||
* <li> Using <code>capture</code> APIs of Snippet</li>
|
||||
* <li> Using log tokens and <code>startCapture</code> and <code>endCapture</code> APIs </li>
|
||||
* </ol>
|
||||
* <p>
|
||||
* Snippet's capture() API accepts a lambda and measures the time it takes to execute it and logs it
|
||||
* on the log cat.
|
||||
* Example usage with <code>Snippet.capture</code>:
|
||||
* <pre>
|
||||
* {@code
|
||||
|
@ -64,10 +74,12 @@ import java.util.Locale;
|
|||
* Here library is going to measure time used to execute the code represented by the underlying lambda.
|
||||
* <p>
|
||||
* When you intent to measure the execution times for code which is not spread across multiple
|
||||
* methods and classes, capture APIs can be used. There is one caveat though, while capturing, we pass
|
||||
* methods and classes, capture() API can be used. There is one caveat though, while capturing, we pass
|
||||
* a lambda for the closure representing the code snippet, this might be a problem if we want to capture
|
||||
* some non final variables outside the scope of lambda(Java does not support that). For that use, {@link Final} to create a
|
||||
* wrapper around your variable and use {@link Final#get()} and {@link Final#set(Object)}()} methods.
|
||||
* This is tedious though, but if you want to use the capture based approach this is the way out. The new
|
||||
* approach for this use case is described in the next section.
|
||||
* <p>
|
||||
* Another approach is through {@link Snippet#startCapture()} & {@link LogToken#endCapture()} APIs.
|
||||
* <code>startCapture</code> is going to return a token representing your execution it can be passed
|
||||
|
@ -97,7 +109,7 @@ import java.util.Locale;
|
|||
* </pre>
|
||||
* We can use <code>startCapture()</code> method with a TAG also. This is particularly useful when
|
||||
* the execution is spread across multiple classes. We can use, {@link Snippet#find(String)} to find
|
||||
* the log token that was created with this tag. The logtoken received can be then used normally.
|
||||
* the log token that was created with this tag. The log token received can be then used normally.
|
||||
* {@link LogToken} objects are internally obtained through a pool so, Snippet tries it best to
|
||||
* recycle the objects again and again.
|
||||
* <p>
|
||||
|
@ -106,7 +118,7 @@ import java.util.Locale;
|
|||
* While this is global filter for all the logs, you can still choose to have a different filter for a
|
||||
* particular LogToken using {@link LogToken#overrideFilter(String)} which will override the global filter.
|
||||
* <p>
|
||||
* Snippet can print Class, Method and Line number information in the logs as a part of execution
|
||||
* Snippet can print class, method and line number information in the logs as a part of execution
|
||||
* context. By default it prints class and method name. You can choose to have your combination of
|
||||
* details through {@link Snippet#addFlag(int)}
|
||||
* <b>Valid options are:</b>
|
||||
|
@ -133,20 +145,52 @@ import java.util.Locale;
|
|||
* {@link LogToken#isThreadLockEnabled()} can be used.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* <p> There is a interesting concept of splits:
|
||||
* There are times while you are measuring a sequence of code and you would like to measure how
|
||||
* much time some steps take within that sequence. As an example, while you are measuring some
|
||||
* method that takes 300ms to execute, it could have multiple areas inside it that could be adding up
|
||||
* to that number. So, to measure that {@link LogToken#addSplit()} and {@link LogToken#addSplit(String)}
|
||||
* could be used. Each call to add split print the time takes since the last addSplit() was called.
|
||||
* If addSplit() is called for the first time, then it would measure the time from startCapture().
|
||||
* Once the endCapture() is called and there are {@link Split} inside your capture, snippet also prints
|
||||
* a clean split summary that shows what was the fraction of time each split took to give an overall idea to
|
||||
* the user.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Snippet also introduces a concept of {@link ExecutionPath}. It is a routing mechanism where, it
|
||||
* tell the library the way to route its code. Whenever an Snippet API is called, it relays it to an execution path.
|
||||
* That directs it to the core library functionality. So, this provides a capability where the user can
|
||||
* provide custom execution path implementations and make Snippet run their own code. It also provides a
|
||||
* mechanism to run different execution paths in different build types. Just add a check for your build type and
|
||||
* install the execution path that you want using {@link Snippet#install(ExecutionPath)} method.
|
||||
* <p>
|
||||
* If your aim is to do the measurement then {@link MeasuredExecutionPath} is already shipped with Snippet.
|
||||
* Any additional work could be added by extending {@link MeasuredExecutionPath}.
|
||||
*
|
||||
* <b> Steps to implement a custom path. See FileExecutionPath in the github sample app for a demo.</b>
|
||||
* 1. Extend ExecutionPath, in our example we will extend MeasuredExecutionPath.
|
||||
* 2. Override {@link ExecutionPath#capture(Closure)} and {@link ExecutionPath#capture(String, Closure)}
|
||||
* This will make sure that you are implementing a custom code for lambda based API.
|
||||
* 3. There are non-contiguous areas of code also, to address that we have {@link Snippet#startCapture()}
|
||||
* {@link Snippet#startCapture(String)} APIs, that returns a log token, so if you are writing a new execution path
|
||||
* you need to provide a custom log token also and the {@link LogToken#endCapture()} and {@link LogToken#endCapture(String)}
|
||||
* so that you can perform the custom actions on all types of code. For doing this extend
|
||||
* {@link com.microsoft.snippet.token.ExtendableLogToken} and override
|
||||
* {@link com.microsoft.snippet.token.ExtendableLogToken#endCapture(String)}, and
|
||||
* {@link ExtendableLogToken#endCapture()}. Once done, return the ExtendableLogToken instance from
|
||||
* {@link Snippet#startCapture(String)}, and {@link Snippet#startCapture(String)} methods.
|
||||
*
|
||||
* NOTE: In almost all the cases, every new execution path that would be created, would require a new
|
||||
* extension of {@link ExtendableLogToken}
|
||||
* </p>
|
||||
*
|
||||
* @author vishalratna
|
||||
*/
|
||||
public final class Snippet {
|
||||
|
||||
public static final AttenuatedLogToken NO_OP_TOKEN = new AttenuatedLogToken();
|
||||
private static final String TAG = LogToken.class.getSimpleName();
|
||||
static final AttenuatedLogToken NO_OP_TOKEN = new AttenuatedLogToken();
|
||||
private static final ExecutionContext EMPTY_CONTEXT = new ExecutionContext();
|
||||
public static final int FLAG_METADATA_CLASS = 1 << 31;
|
||||
public static final int FLAG_METADATA_METHOD = 1 << 30;
|
||||
|
@ -514,7 +558,7 @@ public final class Snippet {
|
|||
this.mFilter = Snippet.primaryFilter;
|
||||
this.mThreadId = -1L;
|
||||
this.mThreadLockEnabled = false;
|
||||
if(this.mSplitRecord != null) {
|
||||
if (this.mSplitRecord != null) {
|
||||
this.mSplitRecord.clear();
|
||||
}
|
||||
this.mSplitRecord = null;
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright © Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
package com.microsoft.snippet;
|
||||
|
||||
/**
|
||||
* Contains the list of areas that are tracked by Snippet. These will help getting the before/after
|
||||
* numbers while doing the PR review.
|
||||
*/
|
||||
public final class SnippetConstants {
|
||||
|
||||
private SnippetConstants() {
|
||||
// private
|
||||
}
|
||||
|
||||
// TTE stands for Time to Execute
|
||||
public static final String SUPER_ON_MAM_CREATE = "TTE super.onMamCreate()";
|
||||
public static final String INIT_SKYPE_DB_HELPER = "TTE SkypeTeamsDBHelper";
|
||||
public static final String INIT_BACKGROUND_OBJ = "TTE Initialize background objects";
|
||||
public static final String INIT_NOTIFICATION_CHANNEL_HELPER = "TTE Initialize notificationChannelHelper";
|
||||
public static final String INIT_NOTIFICATION_MGR = "TTE Initialize notification manager";
|
||||
public static final String SUPER_MA_ON_CREATE = "TTE super.onCreate() MA";
|
||||
public static final String INIT_SEARCH_BAR_VIEW = "TTE SearchBarView MA";
|
||||
public static final String SETUP_CONTENT_VIEW = "TTE SetupContentView";
|
||||
public static final String INJECT_DEPENDENCIES = "TTE injectIfNecessary";
|
||||
public static final String SETUP_TOOLBAR = "TTE setupToolBar";
|
||||
public static final String MA_LOAD_INACTIVE_TABS_UI_THREAD_WORK = "TTE loadInactiveTabs() UI thread Work";
|
||||
public static final String MA_LOAD_SELECTED_FRAGMENT = "TTE load selected fragment";
|
||||
public static final String DEPENDENCY_INJECTION = "TTE Dependency injection";
|
||||
public static final String BOTTOM_BAR_APP_CLICK_TELEMETRY = "Bottom Bar App Click Telemetry";
|
||||
}
|
|
@ -1,7 +1,19 @@
|
|||
package com.microsoft.snippet;
|
||||
|
||||
import androidx.annotation.RestrictTo;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Split is a sub section of code within a capture( a contiguous/non-contiguous section of code).
|
||||
* It is used to measure the duration of subsections and helps in double clicking the areas that are
|
||||
* are creating problems.
|
||||
*
|
||||
* It is advised to use this only for debugging and investigation purposes. Though in release execution path
|
||||
* all these {@link Snippet.LogToken#addSplit()} calls are noop and none will be coming to your release builds.
|
||||
* But according our understanding it should not be shipped to production. It would make your code look dirty!
|
||||
*/
|
||||
@RestrictTo(RestrictTo.Scope.LIBRARY)
|
||||
public class Split {
|
||||
|
||||
private static final AtomicInteger SEQUENCE = new AtomicInteger(1);
|
||||
|
|
|
@ -4,11 +4,14 @@
|
|||
|
||||
package com.microsoft.snippet;
|
||||
|
||||
import androidx.annotation.RestrictTo;
|
||||
|
||||
/**
|
||||
* Internal helper class used to extract the execution context of the code which was guarded
|
||||
* by Snippet APIs.
|
||||
* NOT FOR EXTERNAL USE
|
||||
*/
|
||||
@RestrictTo(RestrictTo.Scope.LIBRARY)
|
||||
final class StackAnalyser {
|
||||
static final int API_CAPTURE = 0;
|
||||
static final int API_LOG_TOKEN = 1;
|
||||
|
|
|
@ -7,6 +7,7 @@ package com.microsoft.snippet;
|
|||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RestrictTo;
|
||||
|
||||
import com.microsoft.snippet.token.ILogToken;
|
||||
|
||||
|
@ -20,6 +21,7 @@ import java.util.Set;
|
|||
*
|
||||
* @author vishalratna
|
||||
*/
|
||||
@RestrictTo(RestrictTo.Scope.LIBRARY)
|
||||
class TagHelper implements ILogTokenSearcher {
|
||||
private static final String LOG_TAG = TagHelper.class.getSimpleName();
|
||||
|
||||
|
|
|
@ -6,11 +6,14 @@ package com.microsoft.snippet;
|
|||
|
||||
import android.os.SystemClock;
|
||||
|
||||
import androidx.annotation.RestrictTo;
|
||||
|
||||
import com.microsoft.snippet.token.ILogToken;
|
||||
|
||||
/**
|
||||
* Utility class the houses some helper functions used across the library.
|
||||
*/
|
||||
@RestrictTo(RestrictTo.Scope.LIBRARY)
|
||||
final class ToolBox {
|
||||
|
||||
private ToolBox() {
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
package com.microsoft.snippet;
|
||||
|
||||
import androidx.annotation.RestrictTo;
|
||||
|
||||
/**
|
||||
* Represents a Triple of objects
|
||||
*
|
||||
|
@ -11,6 +13,7 @@ package com.microsoft.snippet;
|
|||
* @param <B> B
|
||||
* @param <C> C
|
||||
*/
|
||||
@RestrictTo(RestrictTo.Scope.LIBRARY)
|
||||
public final class Triple<A, B, C> {
|
||||
A a;
|
||||
B b;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
package com.microsoft.snippet.token;
|
||||
|
||||
import androidx.annotation.RestrictTo;
|
||||
|
||||
import com.microsoft.snippet.ExecutionContext;
|
||||
|
||||
/**
|
||||
|
@ -18,6 +20,7 @@ import com.microsoft.snippet.ExecutionContext;
|
|||
* some activity. As application onCreate() will not be called always, activity might need a
|
||||
* null check after find call, that is avoided by the use of this class.
|
||||
*/
|
||||
@RestrictTo(RestrictTo.Scope.LIBRARY)
|
||||
public final class AttenuatedLogToken implements ILogToken {
|
||||
private static final ExecutionContext NONE_INFO = new ExecutionContext();
|
||||
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
package com.microsoft.snippet.token;
|
||||
|
||||
import com.microsoft.snippet.ExecutionContext;
|
||||
import com.microsoft.snippet.Snippet;
|
||||
|
||||
/**
|
||||
* A decorator over the {@link ILogToken} API that accepts a log token and routes all the calls
|
||||
* from the inner token that is used for creation of this class.
|
||||
* This could be potentially used for scenarios where you have to write a custom execution path
|
||||
* implementation and {@link com.microsoft.snippet.Snippet#startCapture(String)} and {@link Snippet#startCapture()}
|
||||
* return a log token that contains the {@link ExecutionContext}.
|
||||
* Using this token we can use the returned execution context information and do additional work that
|
||||
* we need to perform.
|
||||
*/
|
||||
public class ExtendableLogToken implements ILogToken {
|
||||
|
||||
private final ILogToken mSnippetToken;
|
||||
|
||||
public ExtendableLogToken(ILogToken logToken) {
|
||||
this.mSnippetToken = logToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionContext endCapture(String message) {
|
||||
return mSnippetToken.endCapture(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionContext endCapture() {
|
||||
return mSnippetToken.endCapture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final long getStart() {
|
||||
return mSnippetToken.getStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final long getEnd() {
|
||||
return mSnippetToken.getEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setStart(long start) {
|
||||
mSnippetToken.setStart(start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setEnd(long start) {
|
||||
mSnippetToken.setEnd(start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ILogToken overrideFilter(String newFilter) {
|
||||
return mSnippetToken.overrideFilter(newFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String filter() {
|
||||
return mSnippetToken.filter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final long creatorThreadId() {
|
||||
return mSnippetToken.creatorThreadId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isThreadLockEnabled() {
|
||||
return mSnippetToken.isThreadLockEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ILogToken enableThreadLock() {
|
||||
return mSnippetToken.enableThreadLock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setCreatorThreadId(long threadId) {
|
||||
mSnippetToken.setCreatorThreadId(threadId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void reset() {
|
||||
mSnippetToken.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void addSplit() {
|
||||
mSnippetToken.addSplit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void addSplit(String message) {
|
||||
mSnippetToken.addSplit(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setState(LogTokenState state) {
|
||||
mSnippetToken.setState(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final LogTokenState getState() {
|
||||
return mSnippetToken.getState();
|
||||
}
|
||||
}
|
|
@ -34,14 +34,15 @@ public interface ILogToken {
|
|||
ExecutionContext endCapture(String message);
|
||||
|
||||
/**
|
||||
* ThreadLock: It is a restriction that could be implemented on a log token level where the user
|
||||
* could say that the thread that starts the measurement should only be the one that ends the measurement.
|
||||
* Returns the id of the thread that asked for this log token.
|
||||
*
|
||||
* @return Thread ID.
|
||||
*/
|
||||
long creatorThreadId();
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns whether a thread lock is enabled or not.
|
||||
*/
|
||||
boolean isThreadLockEnabled();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче