ObjectOutputStream.writeStreamHeader()可以重写该方法以在数据头前添加或附加数据.但是,如果该数据基于传递给派生类的构造函数的参数,如:
public class MyObjectOutputStream extends ObjectOutputStream {
public MyObjectOutputStream( int myData, OutputStream out ) throws IOException {
super( out );
m_myData = myData;
}
protected void writeStreamHeader() throws IOException {
write( m_myData ); // WRONG: m_myData not initialized yet
super.writeStreamHeader();
}
private final int m_myData;
}
Run Code Online (Sandbox Code Playgroud)
它不起作用,因为super()在m_myData初始化和super()调用之前调用它writeStreamHeader().我能想到解决这个问题的唯一方法就是使用ThreadLocal:
public class MyObjectOutputStream extends ObjectOutputStream {
public MyObjectOutputStream( int myData, OutputStream out ) throws IOException {
super( thunk( myData, out ) ); …Run Code Online (Sandbox Code Playgroud) 我想在我的应用引擎应用程序中提供一些请求范围的数据.
例子:
我看到这ThreadLocal是GAE的JRE白名单.
ThreadLocal提供这些信息是一种安全的好方法吗?有替代/更好/更容易接受的方式吗?
ThreadLocal如果Java 变量用作实例变量(例如,在生成线程局部对象的方法中),或者它们是否必须始终是静态的,那么Java 变量是否会产生线程局部值?
作为一个例子,假设一个典型的场景,其中初始化非线程安全的类的对象的几个昂贵,需要在单个静态初始化块中实例化,存储在单个类的静态变量中(例如,在Map数据中)结构)从那时起用于许多不同线程的密集处理.
为了实现线程安全,显然必须传递每个静态对象的不同副本.例如,DateFormat需要跨不同线程安全使用的Java 对象.
在网络上可以找到的许多示例中,方法似乎是分别声明每个ThreadLocal变量,在initialValue()方法中实例化新对象,然后使用该get()方法来检索线程局部实例.
如果要创建数十个或数百个这样的对象,每个都有自己的初始化参数,这种方法效率不高.例如,许多SimpleDateFormat对象各有不同的日期模式.
如果对象的实例化可以在循环中完成,该循环在每次迭代中产生不同的值,则在通过适当地初始化相应对象来创建每个值之后,将需要用于产生线程局部实例的通用方法.
基于以上所述,以下通用静态方法不起作用,因为每次调用initialValue()时都会产生相同的引用:
// Each value is an object initialized prior to calling getLocal(...)
public static final <T> T getLocal(final T value)
{
ThreadLocal<T> local = new ThreadLocal<T>()
{
@Override
protected T initialValue()
{
return value;
}
};
return local.get();
}
Run Code Online (Sandbox Code Playgroud)
相反,需要一种在initialValue()中创建新对象的机制.因此,唯一的通用方法可能是使用反射,类似于
private static final <T> T getLocal(
final Constructor<T> constructor, final Object[] initargs)
{
ThreadLocal<T> local …Run Code Online (Sandbox Code Playgroud) 在我的应用程序中,我们正在从SecurityContextHolderAuthentication对象捕获每个事务的用户详细信息。
但这UserID似乎是错误的。下面是代码片段供您参考。
SecurityContext.xml
春季安全3.2-
<security:http auto-config="true">
<!-- Restrict URLs based on role -->
<security:headers>
<security:cache-control/>
<security:content-type-options/>
<security:frame-options policy="DENY"/>
<security:xss-protection/>
</security:headers>
<security:intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/logoutSuccess*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/resources/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/web/forgotPwd/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/web/**" access="ROLE_USER" />
<security:form-login login-page="/login.html" default-target-url="/web/landing/homePage.html"
always-use-default-target="true" authentication-failure-handler-ref="exceptionTranslationFilter" />
<security:logout delete-cookies="JSESSIONID" invalidate-session="true"
logout-success-url="/logout.html" />
<security:session-management session-fixation-protection="newSession" invalid-session-url="/login.html?login_error=sessionexpired" session-authentication-error-url="/login.html?login_error=alreadyLogin">
<security:concurrency-control max-sessions="1" expired-url="/login.html?login_error=duplicateOrsessionexpired" error-if-maximum-exceeded="false" />
</security:session-management>
<security:csrf />
<security:remember-me token-repository-ref="remembermeTokenRepository" key="myAppKey"/>
</security:http>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="userDetailsServiceImpl">
<security:password-encoder ref="passwordEncoder" />
</security:authentication-provider>
</security:authentication-manager> …Run Code Online (Sandbox Code Playgroud) 我有一个关于我应该如何使用ThreadLocal.
背景和情况
有几个单例对象用于ThreadLocal为每个线程创建一个副本。这个单例对象有一个函数foo()。
public class SingletonA {
protected static ThreadLocal<SingletonA> singleton = new ThreadLocal<SingletonA>() {
@Override
protected SingletonA initialValue() {
return new SingletonA();
}
};
private SingletonA() { ... }
public static SingletonA getInstance() { return singleton.get(); }
public static void remove() { singleton.remove(); }
public static void foo() { ... }
}
Run Code Online (Sandbox Code Playgroud)
... 有 SingletonB、SingletonC 等等。
有一个单例存储库可以缓存ThreadLocal上面的单例。这个类也是一个ThreadLocal单例——
public class SingletonRepo {
protected static ThreadLocal<SingletonRepo> singleton = new ThreadLocal<SingletonRepo>() { …Run Code Online (Sandbox Code Playgroud) 我试图避免在我的Android应用程序中为每个片段创建和管理Realm对象.我认为ThreadLocalVariable可能是一个好的开始.
public class RealmInstanceGenerator extends ThreadLocal<Realm> {
public Realm getRealmForMyThread(Context context) {
if(get() == null && context != null)
super.set(Realm.getInstance(context));
return get();
}
public void setRealmForCurrentThread(Context context) {
if(context != null)
super.set(Realm.getInstance(context));
}
@Override
protected Realm initialValue() {
return null;
}
@Override
public void remove() {
if(get() != null) get().close();
super.remove();
}
}
Run Code Online (Sandbox Code Playgroud)
我只想在我的utils单例类中创建一个静态最终对象RealmInstanceGenerator,并在我的MainActivity中调用setRealmForCurrentThread.然后我会在活动结束时调用remove.对于任何新线程,将自动生成新的Realm对象.这是一个好策略吗?
我目前正在开发基于 RESTeasy 的 RESTful 服务。我有一个过滤器类,它用作服务器请求过滤器和服务器响应过滤器(即它实现ContainerRequestFilter和ContainerResponseFilter接口)。
在请求开始时,我使用过滤器将一个对象放入ThreadLocal. 这个对象在整个请求中被资源使用。在请求结束时,在发送响应之前,过滤器从 中删除对象ThreadLocal。
我的问题是是否可以保证请求过滤器、资源和响应过滤器都将在同一线程中执行?是否有可能在请求过滤器将对象放入 之后ThreadLocal,另一个线程将执行请求(因此无法访问该对象)?
我确信情况确实如此,但后来我看到了这个http://jersey.576304.n2.nabble.com/Does-filter-method-of-ContainerRequestFilter-run-in-resource-method-thread-td7582648.html(泽西官方论坛)现在我有疑问。
这种thread_local存储持续时间的用法是否有任何警告:
template <class T>
inline T &thread_local_get()
{
thread_local T t;
return t;
}
Run Code Online (Sandbox Code Playgroud)
然后在不同的线程中(例如)
thread_local_get<float>() += 1.f;
Run Code Online (Sandbox Code Playgroud)
cppreference 上的文档说明了线程本地存储持续时间:
线程存储持续时间。对象在线程开始时分配,在线程结束时释放。每个线程都有自己的对象实例。只有声明为 thread_local 的对象具有此存储持续时间。thread_local 可以与 static 或 extern 一起出现以调整链接。
这是否thread_local为每个 T(编译期间)和每个调用线程正确分配了一个实例?是否有任何情况会导致例如未定义的行为?
import java.util.concurrent.Executors
import scala.concurrent.{ExecutionContext, Future}
object TestInheritableThreadLocal {
def main(args: Array[String]): Unit = {
implicit val ec = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(2))
val tl: InheritableThreadLocal[String] = new InheritableThreadLocal[String]()
tl.set("InitialValue")
Future {
println("111 " + Thread.currentThread() + tl.get())
Future {
println("222 " + Thread.currentThread() + tl.get())
}
}
Thread.sleep(3000)
Future {
tl.set("NewInitialValue")
println("333 " + Thread.currentThread() + tl.get())
Future {
println("444 " + Thread.currentThread() + tl.get())
}
Thread.sleep(3000)
}
}
}
Run Code Online (Sandbox Code Playgroud)
产量
111 Thread[pool-1-thread-1,5,main]InitialValue
222 Thread[pool-1-thread-2,5,main]InitialValue
333 Thread[pool-1-thread-1,5,main]NewInitialValue
444 Thread[pool-1-thread-2,5,main]InitialValue
Run Code Online (Sandbox Code Playgroud)
我期待输出的最后一行中的"NewInitialValue",因为333 Thread产生了Thread 444,而tl是一个可继承的本地线程.
是什么导致了这个问题,如何解决?
我有一个线程,它包含ThreadLocal变量。我需要parallelStream()在上面提到的线程中使用。需要调用myService哪个使用线程局部变量。有什么机制可以在java8.x中ThreadLocal使用parallelstream()时设置?
List<MyObject> result = myList.parallelStream().map(myObject -> {
//call myService with the Threadlocal
}).filter(...)
.....;
Run Code Online (Sandbox Code Playgroud) thread-local ×10
java ×7
concurrency ×2
android ×1
c++ ×1
c++11 ×1
constructor ×1
java-8 ×1
java-stream ×1
jax-rs ×1
jersey ×1
principal ×1
realm ×1
resteasy ×1
scala ×1
singleton ×1
spring ×1