|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
还是要自己一点一点写代码,然后编译,改错再编译好那。还有最重要的是.net的编译环境非常好,你甚是不需要了解太多工具,对于简单的系统,你可以之了解一些语法就哦了。
说到ThreadLocal,起首说说这个类的定名。直不雅上看仿佛是个Thread的甚么亲戚,但实在它想表达的意义是线程当地变量,也就是说每个线程本人的变量。它作为一个JDK5今后撑持范型的类,次要是想使用范型把非线程平安的共享变量,封装成绑定线程的平安不共享变量。如许的注释我想我们多数能猜出它的完成思绪:把一个共享变量在每一个线程利用时,初始化一个正本,而且和线程绑定。今后一切的线程对共享变量的操纵都是对线程外部谁人正本,完整的线程外部变量的操纵。
要完成如许功效类的计划,次要手艺点是要能把正本和线程绑定映照,程序能够平安查找到以后线程的正本,修正后平安的绑定给线程。以是我们想到了Map的存储布局,ThreadLocal外部就是利用了线程平安的Map情势的存储把currentThread和变量正本逐一映照。
既然要把共享的酿成不共享的,那末就要变量满意一个场景:变量的形态不必要共享。比方无形态的bean在多线程之间是平安的,由于线程之间不必要同步bean的形态,用了就走(很不卖力啊),想用就用。可是关于有形态的bean在线程之间则必需当心,线程A刚看到形态是a,正想使用a办事情,线程B把bean的形态改成了b,了局做了不应做的。可是假如有形态的bean不必要共享形态,每一个线程看到形态a或者b都能够做出本人的举动,这类情形下分歧步的选择就是ThreadLocal了。
使用ThreadLocal的上风就在于基本不必忧虑有形态的bean为了形态的分歧而就义功能,往利用synchronized限定只要一个线程在统一时间做出关于bean形态的举动。而是多个线程同时依据本人持有的bean的正本的形态做出举动,如许的变化关于并发的撑持是那末的难以想象。比方一个Dao内有个Connection的属性,当多个线程利用Dao的统一个实例时,成绩就来了:多个线程用一个Connection,并且它仍是有毗连,封闭等等的形态变化的,我们很敏感的想到这个属性不平安!再看这个属性,实在它是何等的想告知线程哥哥们:我的这些形态基本就不想共享,不要由于我的形态而不敢一同寻求。线程哥哥们也忧郁:你如果有多胞胎姐妹该多好啊!这时候候ThreadLocal年老过去说:小菜,我来弄定!你们这些线程一人一个Connection,你想关就关,想毗连就毗连,不再用埋怨说它把你的毗连关了。如许Dao的实例再也不必由于本人有个不平安的属性而自大了。固然ThreadLocal的思绪固然是很好的,可是官方的说法是最后的完成功能其实不好,跟着Map结构和Thread.currentThread的改善,功能较之synchronized才有了分明的上风。以是如果利用的是JDK1.2,JDK1.3等等,也不要妄图麻雀变凤凰...
再看ThreadLocal和synchronized的实质。前者不在意多占点空间,可是相对的忍耐不了守候;后者对守候无所谓,可是就是不喜好华侈空间。这也反应出了算法的一个纪律:一般是利用场景决意工夫和空间的比例,既省时又省地的算法多半情形下只存在于梦想当中。上面写个复杂的例子注释一下,不外团体以为计划的例子不太好,今后有实践的启示再交换吧。
Java代码
import java.util.concurrent.atomic.AtomicInteger;
/**
* User: yanxuxin
* Date: Dec 14, 2009
* Time: 9:26:41 PM
*/
public class ThreadLocalSample extends Thread {
private OperationSample2 operationSample;
public ThreadLocalSample(OperationSample2 operationSample) {
this.operationSample = operationSample;
}
@Override
public void run() {
operationSample.printAndIncrementNum();
}
public static void main(String[] args) {
final OperationSample2 operation = new OperationSample2();//The shared Object for threads.
for (int i = 0; i < 5; i++) {
new ThreadLocalSample(operation).start();
}
}
}
class OperationSample {
private int num;
//public synchronized void printAndIncrementNum() {
public void printAndIncrementNum() {
for (int i = 0; i < 2; i++) {
System.out.println(Thread.currentThread().getName() + "[id=" + num + "]");
num += 10;
}
}
}
class OperationSample2 {
private static ThreadLocal<Integer> threadArg = new ThreadLocal<Integer>() {
@Override
protected Integer initialValue() {
return 0;
}
};
public void printAndIncrementNum() {
for (int i = 0; i < 2; i++) {
int num = threadArg.get();
threadArg.set(num + 10);
System.out.println(Thread.currentThread().getName() + "[id=" + num + "]");
}
}
}
class OperationSample3 {
private static final AtomicInteger uniqueId = new AtomicInteger(0);
private static ThreadLocal<Integer> threadArg = new ThreadLocal<Integer>() {
@Override
protected Integer initialValue() {
return uniqueId.getAndIncrement();
}
};
public void printAndIncrementNum() {
for (int i = 0; i < 2; i++) {
int num = threadArg.get();
threadArg.set(num + 10);
System.out.println(Thread.currentThread().getName() + "[id=" + num + "]");
}
}
}
<p>
先谈谈我对java的一些认识。我选择java,是因为他语法简单,功能强大,从web,到桌面,到嵌入式,无所不能。但当我进一步了解了java后,感叹,java原来也有许多缺点。 |
|