这一章节我们来讨论一下为什么需要并发?
答案:快和促进代码设计的改进
1.快
先对比一下下面的两个例子:
package com.ray.ch17; import java.util.ArrayList; public class Test { public static void main(String[] args) throws InterruptedException { long startTime = System.currentTimeMillis(); System.out.println("--程序开始--"); System.out.println("working..."); ArrayList<Integer> list = new ArrayList<Integer>(); for (int i = 0; i < 10; i++) { list.add(i); Thread.sleep(100);// 某些操作所需要的时间 } ArrayList<Integer> list2 = new ArrayList<Integer>(); for (int i = 0; i < 10; i++) { list2.add(i); Thread.sleep(100);// 某些操作所需要的时间 } System.out.println("--程序结束--"); long endTime = System.currentTimeMillis(); System.out.println("" + (endTime - startTime)); } }
输出:
--程序开始--
working...
--程序结束--
2015
package com.ray.ch17; import java.util.ArrayList; import java.util.concurrent.CountDownLatch; public class Test2 { public static void main(String[] args) throws InterruptedException { long startTime = System.currentTimeMillis(); System.out.println("--程序开始--"); System.out.println("working..."); CountDownLatch countDownLatch = new CountDownLatch(2); ThreadOne threadOne = new ThreadOne(countDownLatch); ThreadTwo threadTwo = new ThreadTwo(countDownLatch); Thread thread1 = new Thread(threadOne); Thread thread2 = new Thread(threadTwo); thread1.start(); thread2.start(); countDownLatch.await(); System.out.println("--程序结束--"); long endTime = System.currentTimeMillis(); System.out.println("" + (endTime - startTime)); } } class ThreadOne implements Runnable { private CountDownLatch countDownLatch; public ThreadOne(CountDownLatch countDownLatch) { this.countDownLatch = countDownLatch; } @Override public void run() { ArrayList<Integer> list = new ArrayList<Integer>(); for (int i = 0; i < 10; i++) { list.add(i); try { Thread.sleep(100);// 某些操作所需要的时间 } catch (InterruptedException e) { e.printStackTrace(); } } countDownLatch.countDown(); } } class ThreadTwo implements Runnable { private CountDownLatch countDownLatch; public ThreadTwo(CountDownLatch countDownLatch) { this.countDownLatch = countDownLatch; } @Override public void run() { ArrayList<Integer> list = new ArrayList<Integer>(); for (int i = 0; i < 10; i++) { list.add(i); try { Thread.sleep(100);// 某些操作所需要的时间 } catch (InterruptedException e) { e.printStackTrace(); } } countDownLatch.countDown(); } }
输出:
--程序开始--
working...
--程序结束--
1016
从上面两个例子的输出可以看出,大家同样都是向两个list里面添加数据,中间都是有操作时间,但是第二个使用并发,也就是多线程的例子明显比上面的那个要快。
因为在我们的操作中,不可避免的有些是需要等待的,如果按照第一个例子的做法,就会形成阻塞,操作是一个一个的按顺序完成,不可以逾越,但是第二种使用多线程,充分利用现在的多cup来处理任务,不再是单线程的线性操作。
我们上面的例子只是小数据量的例子,当上升到处理百万基本甚至亿级的时候,多线程的性能就会更加的显示出来。
2.促进代码设计的改进
例子:
package com.ray.ch16; public class Test { public static void main(String[] args) { //操作1 //操作2 //操作3 } }
但是,当引入并发后,由于只是某个操作需要并发,其他的不需要,那么现在就要去程序员把这个方法分解处理,形成各种方法,然后进一步方法间的解耦。
package com.ray.ch16; public class Test { public void methodA() {// 操作1 } public synchronized void methodB() {// 操作2 } public void methodC() {// 操作3 } public void method() { methodA(); methodB(); methodC(); } public static void main(String[] args) { new Test().method(); } }
总结:这一章节通过两个例子的对比,得出为什么需要并发。
这一章节就到这里,谢谢。
-----------------------------------
目录