首页 > 编程语言 > 详细

Java并发深度学习(一)

时间:2015-08-19 02:20:42      阅读:267      评论:0      收藏:0      [点我收藏+]

并发编程简介

并发编程可以帮助我们将程序划分为多个分离的、独立运行的任务。通过多线程机制,这些独立任务中的每一个都将由执行线程来驱动。一个线程就是在进程中的一个单一的顺序控制流,因此单个进程可以拥有多个并发执行的任务,但是程序使得每个任务都好像拥有自己的CPU一样,其底层机制是切分CPU时间。CPU会轮流为每个任务分配占用时间。

线程共享静态变量

每个线程拥有各自独立的地址空间,而其中的静态成员变量是可以被多个线程共享的,例如下面程序中的i,i的地址是唯一的,并且永远存放在静态区域,因此,每次对i进行加载读取写入都是有可能发生不正当竞争的,为了保证读写安全,特别对i进行加锁synchronized,这样保证了安全读写。

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package concurrency;
/**
?* 并发问题,多线程的静态变量可以共享i
?* @author zzw922cn
?*
?*/
public class CountRunnable implements Runnable {
?
????private static Integer i=0;
????@Override
????public void run() {
????????synchronized(i) {
????????????System.out.println(Thread.currentThread().getName()+":"+(++i));
????????}
????}
?????
}

?

?

测试代码:

?

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package concurrency;
?
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
?
public class Test1 {
?
????public static void main(String[] args) {
????????//Executors.newCachedThreadPool()用来新建线程池,如果有空闲线程就使用它,否则就新建新线程
????????ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
????????Thread[] thread = new Thread[10];
????????for(int i=0;i<thread.length;i++) {
????????????thread[i]=new Thread(new CountRunnable());
????????????newCachedThreadPool.submit(thread[i]);
????????}
????????newCachedThreadPool.shutdown();
????}
}

?

?

测试结果:

?

?

1
2
3
4
5
6
7
8
9
10
pool-1-thread-2:2
pool-1-thread-4:4
pool-1-thread-3:3
pool-1-thread-1:1
pool-1-thread-5:5
pool-1-thread-6:6
pool-1-thread-7:7
pool-1-thread-8:8
pool-1-thread-10:9
pool-1-thread-9:10

?

?

从任务中返回值(Callable接口)

有时候,我们在分割任务时,同时还希望每个任务执行完毕能够返回一些数据给主进程,这时候我们可以使用实现Callable接口的方式来实现。Callable是个泛型接口,其中必须要实现的方法是Call()方法,该方法的返回值即该任务向主线程提交的返回值,由于是泛型的,因此我们可以返回任意类型的对象。

下面,我们来进行多个求和任务的分割,代码如下:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package concurrency;
?
import java.util.concurrent.Callable;
?
public class CountNumberTask implements Callable<Integer> {
?
????private int num;
?????
????/**
?????* 构造函数
?????* @param num 末尾数
?????*/
????public CountNumberTask(int num) {
????????this.num = num;
????}
?
????/**
?????* 实现call函数,返回结果
?????*/
????@Override
????public Integer call() throws Exception {
????????int sum=0;
????????for(int i=1;i<=num;i++) {
????????????sum+=i;
????????}
????????return sum;
????}
?
}

?

?

测试代码:

?

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package concurrency;
?
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
?* 耗时26秒
?* @author zzw922cn
?*
?*/
public class CountNumberTest {
?
????public static void main(String[] args) {
????????long t1 = System.currentTimeMillis();
????????ExecutorService newCachedThreadPool = Executors.newFixedThreadPool(2);
????????for(int i=1;i<=300000;i++) {
????????????Future<Integer> submit = newCachedThreadPool.submit(new CountNumberTask(i));
????????????try {
????????????????Integer integer = submit.get();
????????????????System.out.println(integer);
????????????} catch (InterruptedException | ExecutionException e) {
????????????????e.printStackTrace();
????????????}
????????}
????????newCachedThreadPool.shutdown();
????????long t2 = System.currentTimeMillis();
????????System.out.println("多线程耗时"+(t2-t1)/1000.0+"s");
????}
}

?

?

为了与传统的单线程方法进行比较,为此也写了一个单线程的程序:

?

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package concurrency;
?
/**
?* 耗时37秒
?* @author zzw922cn
?*
?*/
public class CountNumberTest2 {
?
????public static void main(String[] args) {
????????long t1 = System.currentTimeMillis();
????????for(int i=1;i<=300000;i++) {
????????????int sum=0;
????????????for(int j=0;j<=i;j++) {
????????????????sum+=j;
????????????}
????????????System.out.println(sum);
????????}
????????long t2 = System.currentTimeMillis();
????????System.out.println("单线程耗时"+(t2-t1)/1000.0+"s");
????}
}

?

?

通过运行后,发现使用多线程耗时26s,单线程花了37s。

?

守护线程

所谓守护线程(又称作后台线程),是指在程序运行的时候在后台提供一种通用服务的线程,并且这种线程并不属于程序中不可或缺的一部分。当所有非守护进程结束时,程序就终止了,同时也会杀死程序的所有守护线程,守护线程在被杀死时,不会执行finally语句块。

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package concurrency;
?
public class DeamonRunnable implements Runnable {
?
????@Override
????public void run() {
????????try {
????????????while(true) {
????????????????Thread.sleep(100);
????????????????System.out.println(Thread.currentThread()+" "+this);
????????????}
????????} catch(InterruptedException ex) {
????????????System.out.println("Sleep() interrupted!");
????????}
????}
}

?

?

测试类:

?

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package concurrency;
?
import java.util.concurrent.TimeUnit;
?
public class DeamonRunnableTest {
?
????public static void main(String[] args) throws InterruptedException {
????????for(int i=0;i<10;i++) {
????????????Thread thread = new Thread(new DeamonRunnable());
????????????thread.setDaemon(true);
????????????thread.start();
????????}
????????//设置主线程休眠,所以能看到守护线程
????????TimeUnit.MILLISECONDS.sleep(175);
????}
}

?

?

测试结果:

?

?

1
2
3
4
5
6
7
8
9
10
Thread[Thread-1,5,main] concurrency.DeamonRunnable@4908d73b
Thread[Thread-6,5,main] concurrency.DeamonRunnable@3f91c80b
Thread[Thread-5,5,main] concurrency.DeamonRunnable@1fb44aeb
Thread[Thread-0,5,main] concurrency.DeamonRunnable@12d4f26
Thread[Thread-2,5,main] concurrency.DeamonRunnable@210c4256
Thread[Thread-4,5,main] concurrency.DeamonRunnable@65c16078
Thread[Thread-3,5,main] concurrency.DeamonRunnable@7dca373f
Thread[Thread-9,5,main] concurrency.DeamonRunnable@7105d5e
Thread[Thread-8,5,main] concurrency.DeamonRunnable@7995373b
Thread[Thread-7,5,main] concurrency.DeamonRunnable@6bad1bc1

?

?

守护线程的子线程

通过下面的代码运行结果我们会发现,对于守护线程而言,它的所有子线程也都是守护线程。

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package concurrency;
?
public class Daemon implements Runnable {
?
????private Thread[] t=new Thread[10];
????@Override
????public void run() {
????????// TODO Auto-generated method stub
????????for(int i=0;i<t.length;i++) {
????????????t[i]=new Thread(new DaemonSpawn());
????????????t[i].start();
????????????System.out.println(t[i]+"has started!");
????????}
?????????
????????for(int i=0;i<t.length;i++) {
????????????System.out.println(t[i]+"is DaemonThread:"+t[i].isDaemon());
????????}
?????????
????????while(true) {
????????????Thread.yield();
????????}
????}
?
}

?

?

1
2
3
4
5
6
7
8
9
10
11
12
13
package concurrency;
?
public class DaemonSpawn implements Runnable {
?
????@Override
????public void run() {
????????while(true) {
????????????//让步
????????????Thread.yield();
????????}
????}
?
}

?

?

测试代码:

?

?

1
2
3
4
5
6
7
8
9
10
11
12
package concurrency;
?
public class DaemonTest {
?
????public static void main(String[] args) throws InterruptedException {
????????Thread thread = new Thread(new Daemon());
????????thread.setDaemon(true);
????????thread.start();
????????System.out.println(thread+"isDaemonThread:"+thread.isDaemon());
????????Thread.sleep(100);
????}
}

?

?

测试结果:

?

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Thread[Thread-0,5,main]isDaemonThread:true
Thread[Thread-1,5,main]has started!
Thread[Thread-2,5,main]has started!
Thread[Thread-3,5,main]has started!
Thread[Thread-4,5,main]has started!
Thread[Thread-5,5,main]has started!
Thread[Thread-6,5,main]has started!
Thread[Thread-7,5,main]has started!
Thread[Thread-8,5,main]has started!
Thread[Thread-9,5,main]has started!
Thread[Thread-10,5,main]has started!
Thread[Thread-1,5,main]is DaemonThread:true
Thread[Thread-2,5,main]is DaemonThread:true
Thread[Thread-3,5,main]is DaemonThread:true
Thread[Thread-4,5,main]is DaemonThread:true
Thread[Thread-5,5,main]is DaemonThread:true
Thread[Thread-6,5,main]is DaemonThread:true
Thread[Thread-7,5,main]is DaemonThread:true
Thread[Thread-8,5,main]is DaemonThread:true
Thread[Thread-9,5,main]is DaemonThread:true
Thread[Thread-10,5,main]is DaemonThread:true

最后欢迎大家扫码关注,我们一起学习,进步和交流!?
本公连接也是一个温馨的技术互动交流的小家园,有什么问题随时都可以留言,欢迎大家来访!?


bubuko.com,布布扣
?

Java并发深度学习(一)

原文:http://3264529882.iteye.com/blog/2236414

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!