`
liugang594
  • 浏览: 987503 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java线程类一

 
阅读更多

一、java.util.concurrent.CountDownLatch

通常线程是并发运行,并且不容易预测到哪个线程先执行,哪些后执行,所以通常在执行顺序上是相当公平的。但是,因为创建对象或者执行某些操作总是需要一定的时间,所以还是很难保证真正的公平。这时就需要某种机制来控制线程的运行时机。就比如说赛跑,必须等待所有的选手都已经站在起跑线上才能开始,而java.util.concurrent.CountDownLatch就是这样一个控制器,用于保证所有选手都在起跑线上。

 

例如以下程序: 

		for(int i = 0;i< 10;i++){
			new Thread("Thread "+i){
				public void run() {
					System.out.println(getName()+" started");
				}
			}.start();
			Thread.sleep(50);
		}

如果没有某种保证机制,那基本上可以预测结果如下:

Thread 0 started
Thread 1 started
Thread 2 started
Thread 3 started
Thread 4 started
Thread 5 started
Thread 6 started
Thread 7 started
Thread 8 started
Thread 9 started

因为后面的线程还没开始创建,前面的线程已经启跑了。

 

为了让他们在同一时间开跑,而不管创建的时机,可以如下:

//创建CountDownLatch,并指定countDown必须被调用10次
final CountDownLatch countDownLatch = new CountDownLatch(10);

for(int i = 0;i< 10;i++){
	new Thread("Thread "+i){
		public void run() {
			try {
				//在继续运行之前等待条件满足,也即所有的线程都准备好
				countDownLatch.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(getName()+" started");
		}
	}.start();
	Thread.sleep(50);
	//每创建完一个线程,调用一次countDown()方法,当高用到10次时,即条件满足
	countDownLatch.countDown();
}

下面是某次运行的结果:

Thread 0 started
Thread 8 started
Thread 7 started
Thread 6 started
Thread 5 started
Thread 1 started
Thread 3 started
Thread 2 started
Thread 4 started
Thread 9 started

同上面的结果比较,可以看出,结果基本已经是不可测的了。并且,所以的线程会在等待了差不多半秒之后同步运行。

 

简单的说 java.util.concurrent.CountDownLatch 就是一个倒数器,倒数到 0 后就开始执行所有等待的操作。

 

二、java.util.concurrent.CyclicBarrier

上面的 java.util.concurrent.CountDownLatch 可以用于控制线程同时执行,而 java.util.concurrent.CyclicBarrier 则可以用来控制线程收尾工作。例如,还是上面那个线程,如果我们想在所有的线程执行完后,再打印一下 Done ,则可以如下实现:

final CyclicBarrier cyclicBarrier = new CyclicBarrier(10, new Runnable() {
	
	@Override
	public void run() {
		System.out.println("Done");
	}
});

for(int i = 0; i<10;i++){
	new Thread("Thread "+i){
		public void run() {
			System.out.println(getName());
			try {
				cyclicBarrier.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (BrokenBarrierException e) {
				e.printStackTrace();
			}
		}
	}.start();
}

运行结果如下:

Thread 0
Thread 1
Thread 5
Thread 3
Thread 6
Thread 4
Thread 7
Thread 8
Thread 2
Thread 9
Done

根据提示可以看到,它可以用于做收尾工作,比如说我们有一个查找程序,其中使用了多线程去分别查找,然后可以最后使用 CyclicBarrier 来将结果合并(当然也有其他的方法,这里只是说它可以做这件事)。

三、java.util.concurrent.Semaphore

信号量用于控制同时访问某一资源的线程数,例如系统上的某个文件,只想被最多5个线程同时使用,就可以用信号量在控制了。每次同过 acquire() 方法,获取访问权限,同时信号量减1,当信号量减为0时则不能有新的线程再获得权限;用release()方法释放权限,信号量加1,则可以有新的线程获得权限,例如:

		final Semaphore semaphore = new Semaphore(2, true);
		
		for(int i = 0;i<5;i++){
			new Thread("Thread "+i){
				public void run() {
					try {
						String threadName = getName();
						System.out.println(threadName+"\t is waiting");
						semaphore.acquire();
						System.out.println(threadName+"\t is running");
						sleep(30000);
						System.out.println(threadName+"\t is finished");
					} catch (InterruptedException e) {
						e.printStackTrace();
					}finally{
						semaphore.release();
					}
				}
				
			}.start();
		}

某次运行的结果:

Thread 0	 is waiting
Thread 1	 is waiting
Thread 1	 is running
Thread 3	 is waiting
Thread 4	 is waiting
Thread 0	 is running
Thread 2	 is waiting

可以看到,5个线程都启动了,但是只有2个线程进入了running状态,其他3个处于waiting状态,30秒之后,先前2个running状态的线程finish了之后,剩下其中2个等待的线程才有机会开始进入运行状态:

Thread 1	 is finished
Thread 0	 is finished
Thread 3	 is running
Thread 4	 is running

 

四、java.util.concurrent.Phaser

Java 7中新增了Phaser类,它有点类似于上面介绍的CyclicBarrier和CountDownLatch,但是它支持多阶段的运行/等待,并且支持增加移除观察者。比如说某个操作需要3步完成,其中每一步都需要多个线程配合:

		final Phaser phaser = new Phaser(5);
		for(int i = 0;i<5;i++){
			new Thread("Thread "+i){
				public void run() {
					System.out.println(getName()+" are ready");
					phaser.arriveAndAwaitAdvance();
					System.out.println(getName()+" finished phase1");
					
					phaser.arriveAndAwaitAdvance();
					System.out.println(getName()+" finished phase2");
				}
			}.start();
		}

 某次运行的结果可能如下:

Thread 0 are ready
Thread 2 are ready
Thread 1 are ready
Thread 3 are ready
Thread 4 are ready
Thread 4 finished phase1
Thread 1 finished phase1
Thread 3 finished phase1
Thread 0 finished phase1
Thread 2 finished phase1
Thread 2 finished phase2
Thread 1 finished phase2
Thread 3 finished phase2
Thread 0 finished phase2
Thread 4 finished phase2

 也可以像CyclicBarrier一样,当满足某个条件时才开始工作,例如:

		final Phaser phaser = new Phaser(5);
		phaser.register();
		for(int i = 0;i<5;i++){
			new Thread("Thread "+i){
				public void run() {
					System.out.println(getName()+" are ready");
					phaser.arriveAndAwaitAdvance();
					System.out.println(getName()+" finished phase1");
					
					phaser.arriveAndAwaitAdvance();
					System.out.println(getName()+" finished phase2");
				}
			}.start();
		}
		System.out.println("Wait for a moment before start");
		Thread.sleep(2000);
		phaser.arriveAndDeregister();

一开始可能输出:

Thread 0 are ready
Thread 2 are ready
Thread 1 are ready
Wait for a moment before start
Thread 3 are ready
Thread 4 are ready

2秒后接着输出:

Thread 3 finished phase1
Thread 0 finished phase1
Thread 2 finished phase1
Thread 4 finished phase1
Thread 1 finished phase1
Thread 1 finished phase2
Thread 3 finished phase2
Thread 4 finished phase2
Thread 2 finished phase2
Thread 0 finished phase2

 可以通过重写它的onAdvance()方法来实现在每个阶段结束后执行某个自定义的操作:

		final Phaser phaser = new Phaser(5){
			@Override
			protected boolean onAdvance(int phase, int registeredParties) {
				System.out.println("============="+phase+"=============");
				return super.onAdvance(phase, registeredParties);
			}
		};
		phaser.register();
		for(int i = 0;i<5;i++){
			new Thread("Thread "+i){
				public void run() {
					System.out.println(getName()+" are ready");
					phaser.arriveAndAwaitAdvance();
					System.out.println(getName()+" finished phase1");
					
					phaser.arriveAndAwaitAdvance();
					System.out.println(getName()+" finished phase2");
				}
			}.start();
		}
		System.out.println("Wait for a moment before start");
		Thread.sleep(2000);
		phaser.arriveAndDeregister();

这里在每个阶段的条件满足后插入一段分隔符,输出结果可能为:

Thread 0 are ready
Thread 2 are ready
Thread 1 are ready
Wait for a moment before start
Thread 4 are ready
Thread 3 are ready
=============0=============
Thread 3 finished phase1
Thread 1 finished phase1
Thread 2 finished phase1
Thread 0 finished phase1
Thread 4 finished phase1
=============1=============
Thread 4 finished phase2
Thread 3 finished phase2
Thread 2 finished phase2
Thread 0 finished phase2
Thread 1 finished phase2

 

 

分享到:
评论

相关推荐

    java 线程工具类 java 线程工具类

    java 线程工具类 java 线程工具类java 线程工具类 java 线程工具类java 线程工具类 java 线程工具类java 线程工具类 java 线程工具类java 线程工具类 java 线程工具类java 线程工具类 java 线程工具类java 线程工具...

    java 线程相关工具类

    java 线程相关工具类.java 线程相关工具类.java 线程相关工具类.java 线程相关工具类.java 线程相关工具类.java 线程相关工具类.java 线程相关工具类.java 线程相关工具类.java 线程相关工具类.java 线程相关工具类....

    线程 JAVA java线程 java线程第3版 java线程第2版第3版合集

    电子书相关:包含4个有关JAVA线程的电子书(几乎涵盖全部有关线程的书籍) OReilly.Java.Threads.3rd.Edition.Sep.2004.eBook-DDU Java Thread Programming (Sams) java线程第二版中英文 java线程第二版中英文 ...

    java线程.pdf

    下面将围绕“Java线程”这一主题展开详细的介绍与解释。 ### Java线程基础 在Java语言中,线程是程序执行流的基本单元。一个标准的Java应用程序至少会有一个线程,即主线程,用于执行程序的主要逻辑。通过创建多个...

    JAVA 线程类应用

    Java线程类应用是Java编程中的重要组成部分,它关乎到多任务处理和程序并发执行的能力。在Java中,线程是程序执行的最小单位,它允许一个程序中有多个执行流同时进行,使得程序能更高效地利用系统资源,特别是在处理...

    java多线程Demo

    Java线程有10个优先级(MIN_PRIORITY, NORM_PRIORITY, MAX_PRIORITY),默认优先级是NORM_PRIORITY。但是,线程优先级并不保证绝对的执行顺序,操作系统调度策略可能影响实际执行顺序。 7. join()方法: 一个线程...

    Java线程详解大全

    Java线程是并发编程的核心部分,它允许程序在同一时间执行多个独立的任务,从而提高系统效率和响应速度。本文将深入探讨Java线程的概念、生命周期、实现方式以及相关的同步机制。 首先,理解线程的基本概念至关重要...

    java 线程 dump 分析工具 2.3.3

    Java的TDA线程转储分析器是一个用于分析Sun Java VM生成的线程转储和堆信息的小型Swing GUI(目前用1.4测试)。它从提供的日志文件中解析线程转储和类直方图。它提供关于发现的线程转储的统计信息,提供关于锁定监视器...

    Java线程.ppt

    Java线程是Java编程中的重要概念,特别是在多核处理器和并发处理中不可或缺。Java线程允许程序在同一时间执行多个不同的任务,从而提高了程序的效率和响应性。在燕山大学信息学院计算机系的课程中,李峰教授讲解了...

    Java线程使用教程

    Java线程是Java编程语言中的一个核心概念,它允许程序同时执行多个任务,极大地提高了程序的并发性和效率。本教程将深入探讨Java线程的使用,帮助开发者掌握这一关键技术。 一、线程基础 1. **线程的概念**:线程...

    java线程实例 各种小Demo

    1. 继承Thread类:创建一个新的类,继承自Thread类,并重写其run()方法。然后通过创建该类的实例并调用start()方法来启动线程。 2. 实现Runnable接口:创建一个实现了Runnable接口的类,实现run()方法。然后将...

    Java线程(第三版)

    线程优先级和守护线程也是Java线程中的一部分,`Thread`类提供了设置优先级的方法,高优先级的线程更有可能获得CPU执行时间。守护线程是一种特殊的线程,它不会阻止JVM的退出,除非所有的非守护线程都已结束。 书中...

    java线程深入解析

    创建Java线程有两种方式:继承`Thread`类并重写`run()`方法,或者实现`Runnable`接口并提供`run()`方法。当线程对象被创建并调用`start()`方法后,线程进入可运行态,由Java的线程调度器决定何时执行`run()`方法。 ...

    JAVA线程dump的分析

    JAVA线程dump的分析 JAVA线程dump是指在JAVA程序中,当前线程的状态和调用堆栈的快照,能够帮助开发者了解当前程序的执行情况,诊断问题和性能瓶颈。生成JAVA线程dump的方法在不同的操作系统下是不同的,在Windows...

    java线程文档大全

    Java线程是多任务编程中的核心概念,它允许程序同时执行多个不同的任务,极大地提高了程序的效率和响应性。在Java中,线程是通过Java.lang.Thread类或实现Runnable接口来创建和管理的。这份“java线程文档大全”包含...

    Java多线程知识点总结

    Java多线程是Java编程语言中一个非常重要的概念,它允许开发者在一个程序中创建多个执行线程并行运行,以提高程序的执行效率和响应速度。在Java中,线程的生命周期包含五个基本状态,分别是新建状态(New)、就绪...

    简单的java线程demo

    Java线程是多任务编程的重要概念,特别是在大型的、复杂的软件系统中,它允许程序同时执行多个不同的任务,提升程序的并发性和效率。本示例"简单的Java线程demo"旨在帮助初学者理解如何在Java中创建和管理线程。 在...

    java线程入门级书籍

    #### 一、Java线程基础知识概述 **1.1 什么是线程?** 线程是程序执行流的最小单元,是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。在Java中,线程是一种轻量级的进程,...

    java线程.rar

    Java线程是Java编程语言中的一个核心概念,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,线程是通过类`Thread`或实现`Runnable`接口来创建和管理的。Java线程模型是基于操作系统的原生...

    Java线程培训资料

    #### 一、Java线程基本概念 1. **如何编写与启动线程** - **方式一:继承Thread类** ```java class MyThread extends Thread { @Override public void run() { // 业务逻辑 } } new MyThread().start(); ...

Global site tag (gtag.js) - Google Analytics