反例A
public class ThreadTest {
static int k = 0;
static long time;
public static void main(String[] args) {
// TODO Auto-generated method stub
time = System.currentTimeMillis();
for (int i = 0; i < 2500; i++) {
new Thread() {
@Override
public void run() {
try {
//加入耗时操作
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String str="第"+(++k)+"时间:"+(System.currentTimeMillis() - time);
System.out.println(str);
}
}.start();
}
}
}
得到结果最终结果是 (我的机器为例) 第2471个 耗时:1262
反思:可能没有任何措施使用多线程安全是一个问题,如上并发访问就出现了漏数据的问题。
Thread使用Runnable委托后改写其线程安全访问部分如下
public class RunnableTest {
static int k = 0;
static long time;
public static void main(String[] args) {
// TODO Auto-generated method stub
time = System.currentTimeMillis();
Runnable run = new Runnable() {
@Override
public void run() {
try {
// 加入耗时操作
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (this) {
String str = "第" + (++k) + "个 耗时:"
+ (System.currentTimeMillis() - time);
System.out.println(str);
}
}
};
for (int i = 0; i < 2500; i++) {
new Thread(run).start();
}
}
}
值得注意的是关于synchronized的使用方法,如果将synchronized写在方法中那么
等价于synchronized(this){ .............}
警惕多线程synchronized(this)的陷阱 如下图synchronized总是对新对象加锁
以下是错误认识synchronized的反例 效果与反例A相同
public class ThreadTest {
static int k = 0;
static long time;
public static void main(String[] args) {
// TODO Auto-generated method stub
time = System.currentTimeMillis();
for (int i = 0; i < 2500; i++) {
new Thread() {
@Override
public synchronized void run() {
synchronized (this) {
try {
// 加入耗时操作
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String str = "第" + (++k) + "个 耗时:"
+ (System.currentTimeMillis() - time);
System.out.println(str);
}
}
}.start();
}
}
}
另外使用synchronized同步的代码段尽可能少。这样能提高性能。