之前一直沒有用過多線程皮钠,這次贩绕,寫了一個(gè)多線程查詢數(shù)據(jù)庫的案列,并且比較一下多線程和單線程直接執(zhí)行的效率壶愤,體會(huì)一下多線程同步淑倾。數(shù)據(jù)庫中大概有1 W條數(shù)據(jù)。下面是核心代碼:
單線程一次查詢數(shù)據(jù)庫
TestServiceImpl類
@Override
public List<Store> queryStoresInfo() {
return testDao.queryStoresInfo();
}
單線程For循環(huán)查詢數(shù)據(jù)庫
TestServiceImpl類
@Override
public List<Store> queryStoresInfoByFor() {
List<Store> lists = new ArrayList<>();
for (int i = 0; i < 10; i++) {
List<Store> list = testDao.queryStoresInfo();
lists.addAll(list);
}
return lists;
}
多線程查詢數(shù)據(jù)庫(使用join()進(jìn)行同步)
TestServiceImpl類(下面這個(gè)是我的一個(gè)錯(cuò)誤的做法)
將join寫在循環(huán)內(nèi)征椒,實(shí)際本身還是一個(gè)串行的運(yùn)行過程娇哆。
@Override
public List<Store> queryStoresInfoByThread() throws InterruptedException {
List<Store> lists = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(new TestThread(lists));
thread.start();
thread.join();
}
return lists;
}
TestServiceImpl類(正確的做法)
@Override
public List<Store> queryStoresInfoByThread() throws InterruptedException {
List<Store> lists = new ArrayList<>();
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(new TestThread(lists));
thread.start();
threads.add(thread);
}
for (Thread thread: threads){
thread.join();
}
return lists;
}
TestThread類
public class TestThread implements Runnable {
TestDao testDao = SpringBeanUtils.getBean(TestDao.class);
private List<Store> stores;
public TestThread(List<Store> stores) {
this.stores = stores;
}
@Override
public void run() {
System.err.println(Thread.currentThread().getName() +" query data start...");
List<Store> store = testDao.queryStoresInfo();
synchronized (stores) {
stores.addAll(store);
}
System.err.println(Thread.currentThread().getName() +" query data end...");
}
}
多線程查詢數(shù)據(jù)庫(使用CountDownLatch進(jìn)行同步)
TestServiceImpl類
@Override
public List<Store> queryStoresInfoByThread() throws InterruptedException {
List<Store> lists = new ArrayList<>();
CountDownLatch latch = new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(new TestThread(lists, latch));
thread.start();
}
latch.await();
return lists;
}
TestThread類
public class TestThread implements Runnable {
TestDao testDao = SpringBeanUtils.getBean(TestDao.class);
private List<Store> stores;
private CountDownLatch latch;
public TestThread(List<Store> stores,CountDownLatch latch) {
this.stores = stores;
this.latch = latch;
}
@Override
public void run() {
System.err.println(Thread.currentThread().getName() +" query data start...");
List<Store> store = testDao.queryStoresInfo();
synchronized (stores) {
stores.addAll(store);
}
latch.countDown();
System.err.println(Thread.currentThread().getName() +" query data end...");
}
}
多線程查詢數(shù)據(jù)庫(使用線程池->CountDownLatch進(jìn)行同步)
TestServiceImpl類
@Override
public List<Store> queryStoresInfoByThreadPool() {
ExecutorService executorService = new ThreadPoolExecutor(5, 10, 1, TimeUnit.MINUTES,new ArrayBlockingQueue<Runnable>(10));
List<Store> resultList = new ArrayList<>();
CountDownLatch latch = new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
executorService.execute(new TestThread(resultList,latch));
}
executorService.shutdown();
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return resultList;
}
TestThread類
public class TestThread implements Runnable {
TestDao testDao = SpringBeanUtils.getBean(TestDao.class);
private List<Store> stores;
private CountDownLatch latch;
public TestThread(List<Store> stores,CountDownLatch latch) {
this.stores = stores;
this.latch = latch;
}
@Override
public void run() {
System.err.println(Thread.currentThread().getName() +" query data start...");
List<Store> store = testDao.queryStoresInfo();
synchronized (stores) {
stores.addAll(store);
}
latch.countDown();
System.err.println(Thread.currentThread().getName() +" query data end...");
}
}
運(yùn)行效率比較
single | for | Thread(join) | Thread(latch) | TheadPool |
---|---|---|---|---|
379 ms | 1124 ms | 544 ms | 596 ms | 507 ms |
379 ms | 1193 ms | 500 ms | 548 ms | 493 ms |