您的位置:首页 > 编程语言 > Java开发

从头认识java-17.1 为什么需要并发?

2016-01-07 21:27 513 查看
这一章节我们来讨论一下为什么需要并发?
答案:快和促进代码设计的改进
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();
	}
}

上面的代码是改进后的代码,而且,当上面的方法分解开来,其实每一个小的方法可能即使其他方法的某一个操作,再把其他的方法分解解耦,最后达到代码的整体改进。

总结:这一章节通过两个例子的对比,得出为什么需要并发。

这一章节就到这里,谢谢。-----------------------------------目录
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: