java – 将ThreadLocal与包含静态成员的现有类一起使用
发布时间:2020-12-15 08:30:41 所属栏目:Java 来源:网络整理
导读:我正在尝试使用ThreadLocal为预先存在的非线程安全类提供线程安全性,但遇到问题.似乎没有执行隔离 – 线程仍然共享静态,而不是每个线程的本地. 我相信我的用法几乎与this StackOverflow question中描述的SimpleDateFormatter的示例本地化完全平行,但它并没有
我正在尝试使用ThreadLocal为预先存在的非线程安全类提供线程安全性,但遇到问题.似乎没有执行隔离 – 线程仍然共享静态,而不是每个线程的本地.
我相信我的用法几乎与this StackOverflow question中描述的SimpleDateFormatter的示例本地化完全平行,但它并没有按照我希望的方式运行. 我所希望的是,那些使用过它的人会指出我必须做出的令人震惊的无知错误……所以我想我的问题是:你能发现我在这里做错了什么吗? 这是我的简单课程: public class SimpleClassWithStaticMembers { private static String theStaticString = "StaticStringInClassWithStaticMember"; public void setTheStaticString (String val) { SimpleClassWithStaticMembers.theStaticString = val; } public String getTheStaticString () { return SimpleClassWithStaticMembers.theStaticString; } } 这是创建SimpleClassWithStaticMembers的threadlocal实例的线程类: public class SimpleTesterThread extends Thread { private void showMsg (String msg) { System.out.println (msg); System.out.flush(); } public SimpleTesterThread (String threadId) { super(threadId); } public void run() { try { Thread.sleep(2000); } catch (InterruptedException ex) { } ThreadLocal<SimpleClassWithStaticMembers> localizedClass = new ThreadLocal<SimpleClassWithStaticMembers>(); localizedClass.set(new SimpleClassWithStaticMembers()); // repeating here to be sure we overlap all with all for (int ii=0; ii < 3; ii++) { localizedClass.get().setTheStaticString ("Setby_" + this.getName()); try { Thread.sleep(2000); } catch (InterruptedException ex) { } showMsg(" Thread [" + this.getName() + "] - " + localizedClass.get().getTheStaticString() + "'."); } showMsg ("Thread [" + this.getName() + "] complete. Our 'threadlocal' string is now - " + localizedClass.get().getTheStaticString() + "'."); localizedClass.remove(); } } 当创建10个SimpleTesterThread实例(给它们不同的线程名称,如“AAAAAAAAAA”,“BBBBBBBBB”等),然后启动时,输出清楚地显示它们正在共享实例.日志输出包括: ... Thread [JJJJJJJJJJ] - Setby_CCCCCCCCCC'. Thread [DDDDDDDDDD] - Setby_JJJJJJJJJJ'. Thread [IIIIIIIIII] - Setby_DDDDDDDDDD'. Thread [GGGGGGGGGG] - Setby_IIIIIIIIII'. Thread [EEEEEEEEEE] - Setby_GGGGGGGGGG'. Thread [EEEEEEEEEE] complete. Our 'threadlocal' string is now - Setby_GGGGGGGGGG'. Thread [HHHHHHHHHH] - Setby_GGGGGGGGGG'. Thread [BBBBBBBBBB] - Setby_GGGGGGGGGG'. Thread [FFFFFFFFFF] - Setby_GGGGGGGGGG'. Thread [FFFFFFFFFF] complete. Our 'threadlocal' string is now - Setby_GGGGGGGGGG'. ... Thread [JJJJJJJJJJ] - Setby_GGGGGGGGGG'. Thread [JJJJJJJJJJ] complete. Our 'threadlocal' string is now - Setby_GGGGGGGGGG'. Thread [HHHHHHHHHH] complete. Our 'threadlocal' string is now - Setby_GGGGGGGGGG'. Thread [GGGGGGGGGG] - Setby_GGGGGGGGGG'. Thread [GGGGGGGGGG] complete. Our 'threadlocal' string is now - Setby_GGGGGGGGGG'. Thread [IIIIIIIIII] - Setby_GGGGGGGGGG'. Thread [CCCCCCCCCC] - Setby_GGGGGGGGGG'. Thread [CCCCCCCCCC] complete. Our 'threadlocal' string is now - Setby_GGGGGGGGGG'. Thread [AAAAAAAAAA] complete. Our 'threadlocal' string is now - Setby_GGGGGGGGGG'. Thread [DDDDDDDDDD] - Setby_GGGGGGGGGG'. Thread [DDDDDDDDDD] complete. Our 'threadlocal' string is now - Setby_GGGGGGGGGG'. Thread [IIIIIIIIII] complete. Our 'threadlocal' string is now - Setby_GGGGGGGGGG'. ============== all threads complete. 我没有包含创建,启动和加入线程的类 – 如果感觉有用,我很乐意编辑添加它. 解决方法
具有单独的实例没有帮助,因为所有实例都是相同的静态字段.可变的静力学是邪恶的.
如果你真的无法改变类,你可能只想使用一个锁,这样每个客户端就可以一次使用一个静态字段.如果你想拥有静态字段的不同实例,那么你可能需要使用类加载器(另一个明显的解决方案是重写字节码,这更不令人愉快). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |