多线程一定快吗?
答案是不一定。当并发执行的累积数量一定以内,并行会比串行执行要慢,此处用的测试用例是累加,那么为什么会出现这种情况呢?
这是因为线程的创建的上下文切换的开销
上下文切换
单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制,因为时间片非常短,所以CPU通过不停切换线程执行的,时间一般是即使毫秒(ms)
public class ConcurrencyTest {
private static final long count = 100001;
public static void main(String[] args) throws InterruptedException{
concurrency();
serial();
}
private static void concurrency() throws InterruptedException {
long start = System.currentTimeMillis();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
int a = 0;
for(long i = 0;i<count;i++) {
a += 5;
}
}
});
thread.start();
int b = 0;
for(long i = 0;i<count;i++) {
b--;
}
long time = System.currentTimeMillis()-start;
thread.join();
System.out.println("concurrency:"+time+"ms,"+" b="+b);
}
private static void serial() {
long start = System.currentTimeMillis();
int a = 0;
for(long i =0;i<count;i++) {
a +=5;
}
int b = 0;
for(long i =0;i<count;i++) {
b--;
}
long time = System.currentTimeMillis() - start;
System.out.println("serial:"+time+"ms,"+" b="+b);
}
}
这就像我们同时读两本书,当我们在读一本英文的技术书时,发现某个单词不认识,于是便打开中英文字典,但是在放下英文技术书之前,大脑必须先记住这本书读到了多少页的第多少行,等查完单词之后,能够继续读这本书。这样的切换是会影响读书效率的,同样上下文切换也会影响多线程的执行速度
如何减少上下文切换呢?
无锁并发编程 使用一下办法来避免使用锁
CAS算法 Compare And Swap 即比较和替换
使用最小线程数
死锁列子
package com.hunau;
public class DeadLockDemo {
private static String A = "A";
private static String B = "B";
public static void main(String[] args) {
new DeadLockDemo().deadLock();
}
private void deadLock() {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized(A) {
try {
Thread.currentThread().sleep(2000);
}catch(InterruptedException e) {
e.printStackTrace();
}
synchronized(B) {
System.out.println("1");
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized(B) {
synchronized(A) {
System.out.println("2");
}
}
}
}) ;
t1.start();
t2.start();
}
}