lz有一次为了实现一个功能时做了一个测试,这个测试的大概内容是这样的:
有100个数据,每个线程读取睡眠一秒,如果是一个线程读取的话,需要100秒才能读完,那么开启四个线程的话只用25秒就可以读完。
从理论上来说,这是一个很简单的测试,不管你是用同步关键字做或者锁都可以,所以lz采用了同步关键字进行测试。
public class test{
static ArrayList arr = new ArrayList();
public static void main(String[] args){
System.out.println("begin:"+(System.currentTimeMillis()/1000));
for(int i=0;i<100;i++){
final String log = ""+(i+1);
{
arr.add(log);
}
}
Runnable r = new Runnable() {
int b = 16;
@Override
public void run() {
while(true){
//方法外
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (test4.class) {
if(b>0){
//方法内
System.out.println(Thread.currentThread().getName()+" : "+b--);
}
System.out.println(Thread.currentThread().getName()+":"+b++);*/
}
}
}
};
for (int i = 0; i < 4; i++) {
new Thread(r).start();
}
}
public static void parseLog(String log){
System.out.println(Thread.currentThread().getName()+" : "+log+":"+(System.currentTimeMillis()/1000));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
如上面的代码:
Thread.sleep(1000);如果在方法内部的话那么程序最终执行还是需要100秒,即使开了四个线程也没有作用。
Thread.sleep(1000);如果在方法外的话,那么就可以实现25秒执行完。
lz最开始的时候就时因为写错了格式,将方法写入到同步里面了,当时仔细检查了所有的逻辑也没发现,直到最终突然看到sleep方法位置貌似不对,然后重新调试了下发现问题解决。
lz分析了一下两种的问题根节所在:
1.在方法内部的话,因为有同步,所以只能有一个线程进行访问,启动了四个线程,相当于除了线程本身的睡眠一面(parseLog方法中睡眠),每一次线程的同步都会再次睡眠,那么形象的说就是当同步完成释放锁时,四个线程进行切换,但是每一个进入同步后都会睡眠一秒,所以总体时间不变。
2.在方法外部的话,与1不同的便是,四个线程之间的切换不耗费时间,只是每一个线程在执行run方法是睡眠一秒,所以这样的话,便实现了四个线程访问所需25秒的情况。
每一次的博客即是分享也是对自己的一个总结,未来还很长,大家一起努力吧!