当前位置:首页 > 开发 > 编程语言 > 多线程 > 正文

java线程详解

发表于: 2014-11-20   作者:chendaiming   来源:转载   浏览次数:
摘要:   package test; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Test { private static int t

 

package test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test {
	private static int threadCount = 4;

	//线程辅助类
	private static CountDownLatch countDown = new CountDownLatch(4);

	// 创建线程池,线程数threadCount
	private static ExecutorService exec = Executors.newFixedThreadPool(threadCount);

	public static void main(String[] args) throws InterruptedException {
		thread();
	}

	//堵塞时间(3秒)
	static int sleep = 3000;
	
	private static void thread() throws InterruptedException {
		//循环1
		for (int index = 1; index < 5; index++) {
			System.out.println("任务:"+index);
			final int NO = index;
			Runnable run = new Runnable() {
				public void run() {
					//循环2
					for (int i = 1; i < 5; i++) {
						try {
							//打印i
							System.out.println("i="+i);
							//堵塞
							Thread.sleep(sleep);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						//打印结果
						System.out.println("第" + NO + "次任务," + "第" + i + "次执行!");
					}
					// 递减,每次减一
					countDown.countDown();
				}
			};
			exec.submit(run);
		}
		// 等待线程全部执行完毕,确保程序的流程
		// 当递减为0时,执行
		countDown.await();
		// 关闭
		exec.shutdown();
		System.out.println("finish");
	}
}

 运行结果

任务:1
任务:2
任务:3
任务:4

i=1
i=1
i=1
i=1

第1次任务,第1次执行!
i=2
第3次任务,第1次执行!
i=2
第2次任务,第1次执行!
i=2
第4次任务,第1次执行!
i=2

第1次任务,第2次执行!
i=3
第3次任务,第2次执行!
i=3
第2次任务,第2次执行!
i=3
第4次任务,第2次执行!
i=3

第3次任务,第3次执行!
i=4
第1次任务,第3次执行!
i=4
第2次任务,第3次执行!
i=4
第4次任务,第3次执行!
i=4

第3次任务,第4次执行!
第1次任务,第4次执行!
第2次任务,第4次执行!
第4次任务,第4次执行!

finish

 

代码详解

 

1.主线程main开启后执行到了“循环1”,“循环1“执行了4次,打印结果是(如下),顺序可能会错乱,

”循环1“执行后,4个线程挂起执行,由于Thread.sleep()堵塞的原因,run方法只能先执行到”打印i“代码,堵塞时间设置的3秒,3秒之内,”打印i“代码块已经执行完了,3秒之后会继续执行挂起的任务后面的部分

任务:1
任务:2
任务:3
任务:4
i=1
i=1
i=1
i=1

2.第一次堵塞之后,也就是3秒之后执行Thread.sleep()下面的代码,所以执行”打印结果“代码块,由于线程的原因,打印的任务也是随机的,由于run方法里有”循环2“,所以打印过后执行”打印i“代码块,

第1次任务,第1次执行!
i=2

 3.由于设置了线程池,并且大小是4,所以每次会允许四个线程同时执行

第1次任务,第1次执行!
i=2
第3次任务,第1次执行!
i=2
第2次任务,第1次执行!
i=2
第4次任务,第1次执行!
i=2

 4.按循环执行,直到最后,最后四次没有打印”i=5“,因为最后一次打印循环结束了,”打印i“是在第二次循环中,并不是在本次循环中

 

第3次任务,第4次执行!
第1次任务,第4次执行!
第2次任务,第4次执行!
第4次任务,第4次执行!

 5.最后打印finish

 

 

以下是threadCount=3的代码详解:

 

package test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test6 {
	private static int threadCount = 3;

	//线程辅助类
	private static CountDownLatch countDown = new CountDownLatch(4);

	// 创建线程池,线程数threadCount
	private static ExecutorService exec = Executors.newFixedThreadPool(threadCount);

	public static void main(String[] args) throws InterruptedException {
		thread();
	}

	//堵塞时间(3秒)
	static int sleep = 3000;
	
	private static void thread() throws InterruptedException {
		//循环1
		for (int index = 1; index < 5; index++) {
			System.out.println("任务:"+index);
			final int NO = index;
			Runnable run = new Runnable() {
				public void run() {
					//循环2
					for (int i = 1; i < 5; i++) {
						try {
							//打印i
							System.out.println("i="+i);
							//堵塞
							Thread.sleep(sleep);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						//打印结果
						System.out.println("第" + NO + "次任务," + "第" + i + "次执行!");
					}
					// 递减,每次减一
					countDown.countDown();
				}
			};
			exec.submit(run);
		}
		// 等待线程全部执行完毕,确保程序的流程
		// 当递减为0时,执行
		countDown.await();
		// 关闭
		exec.shutdown();
		System.out.println("finish");
	}
}

 运行结果

任务:1
任务:2
任务:3
任务:4
i=1
i=1
i=1

第2次任务,第1次执行!
i=2
第3次任务,第1次执行!
i=2
第1次任务,第1次执行!
i=2

第2次任务,第2次执行!
i=3
第3次任务,第2次执行!
i=3
第1次任务,第2次执行!
i=3

第2次任务,第3次执行!
i=4
第3次任务,第3次执行!
i=4
第1次任务,第3次执行!
i=4

第2次任务,第4次执行!
i=1
第3次任务,第4次执行!
第1次任务,第4次执行!

第4次任务,第1次执行!
i=2

第4次任务,第2次执行!
i=3

第4次任务,第3次执行!
i=4

第4次任务,第4次执行!

finish

  代码详解

 1.”循环1“执行不变,打印”任务1--任务4“,由于这次线程池中的线程数变成了3,所以只执行了前三个线程,打印了前三次的”i“,打印之后继续执行堵塞之后的代码,并且继续执行”打印i“,一直执行到”i=4“

 

2.打印”i=4“之后,前三个线程已经循环完毕,但是线程堵塞之后的代码还没有执行,也就是”打印结果“,所以当前三个线程中的任意一个线程打印结果之后,线程池空闲出一块,”循环1“中的最后一个线程立即进入,所以看到”第2次任务,第4次执行!“下面打印了”i=1“,但是这个”打印i“的顺序也是随机的,因为可能前三个线程中有两个同时结束,也有可能是三个同时结束

 

3.第四次任务的顺序不会改变,因为就只有一个线程了,会依次打印

 

 

 

以上纯属个人观念,如有错误请指出,谢谢!!

 

 

 

 

 

 

 

 

 

java线程详解

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
Java 线程池学习 Reference: 《创建Java线程池》[1],《Java线程:新特征-线程池》[2], 《Java线程
一:理解多线程 多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线
1.线程的操作方法 1.1设置和取得名字 设置名字 set方法: public final void setName(String name)
synchronized简介   Java提供了一种内置的锁机制来支持原子性:同步代码块(Synchronized Block)。
要求 必备知识 本文要求基本了解JAVA编程知识。 开发环境 windows 7/EditPlus 演示地址 源文件 进程
Java Thread(线程)案例详解sleep和wait的区别 http://www.cnblogs.com/DreamSea/archive/2012/01/16
一、什么是线程 线程是指令的执行路径。在Java语言中,线程无处不在,每一个计算机程序最少都有一个
一、什么是线程 线程是指令的执行路径。在Java语言中,线程无处不在,每一个计算机程序最少都有一个
自:http://janeky.iteye.com/blog/770671 7.BlockingQueue “支持两个附加操作的 Queue,这两个操
线程的概念: 几乎每种操作系统都支持进程的概念 ----进程就是在某种程度上互相隔离的、独立运行的程
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号