Thread类应用,多线程

 关于join方法

调用逻辑

Parent 调用 child.join(),child.join() 再调用 child.join(0) (此时 Parent 会获得 child 实例作为锁,其他线程可以进入 child.join() ,但不可以进入 child.join(0), 因为无法获取锁)。child.join(0) 会不断地检查 child 线程是否是 Active。

如果 child 线程是 Active,则循环调用 child.wait(0)(为了防止 Spurious wakeup, 需要将 wait(0) 放入 for 循环体中;此时 Parent 会释放 child 实例锁,其他线程可以竞争锁并进入 child.join(0)。我们可以得知,可以有多个线程等待某个线程执行完毕)。

一旦 child 线程不为 Active (状态为 TERMINATED), child.join(0) 会直接返回到 child.join(), child.join() 会直接返回到 Parent 父线程,Parent 父线程就可以继续运行下去了。

一些疑问

a. 子线程结束之后,"会唤醒主线程",父线程重新获取cpu执行权,继续运行。

“唤醒”令人误解。并非子线程主动采取了措施去唤醒父线程。父线程重新运行,都是由底层的调度引起的。

 

 b. join() 将几个并行的线程"合并为一个单线程"执行。

我理解提这个说法的人的意思。但是这样描述只会让读者更难理解。

在调用 join() 方法的程序中,原来的多个线程仍然多个线程,并没有发生“合并为一个单线程”。真正发生的是调用 join() 的线程进入 TIMED_WAITING 状态,等待 join() 所属线程运行结束后再继续运行。

package com.lx.threadPool;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import com.lx.bale.TreadPool;

public class Entry {
	public static Object o1 = new Object();
	public static Object o2 = new Object();
	/**
	 * 自定义线程池测试方法
	 * @throws InterruptedException
	 */
	@Test
	public void fun() throws InterruptedException{
		TreadPool pool = new TreadPool(8, 5, 2000);
		for (int i = 1; i <= 10; i++) {
			final int num = i;
			Runnable runnable = new Runnable() {
				@Override
				public void run() {
					System.out.println("线程:"+num+",执行开始");
					try {
						Thread.sleep(6000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("线程:"+num+",执行结束");
				}
				
			};
			pool.excute(runnable);
		}
		
		Thread.sleep(500000);
	}
	
	/**
	 * 关于join
	 * @param args
	 * @throws InterruptedException
	 * 
	 */
	public static void main(String[] args) throws InterruptedException {
		List<Thread> list = new ArrayList<Thread>();
		for (int i = 0; i < 3; i++) {
			final int num = i;
			Thread son = new Thread(new Runnable() {
				public void run() {
					System.out.println("线程" + num +"开始");
					try {
						if (num == 2) {
							Thread.sleep(60000);
						}else{
							Thread.sleep(20000);
						}
						} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println("线程" + num +"结束");
				}
			});
			son.start();
			//son.join();
			list.add(son);
		}
		//Thread.yield();  //放弃持有的monitor 进入等待池和其他线程一起竞争, 有可能再次获得monitor也有可能是别的线程获得
		for (Thread thread : list) {
			//thread.join(1000);
			thread.join();  // join() = join(0) ,当参数为0时, 如果thread线程仍在活动中isAlive(), 则调用线程无限休眠wait(0) ,为什么? 可能是thread结束后调用了notify方法
			System.out.println("加入");
		}
		System.out.println("主线程开始运行");

	}
	
	/**
	 * 关于notify 和  notifyAll
	 *
	 */
	@Test
	public void fun02() throws InterruptedException{
		/**
		 * 调用wait(),notify()和notifyAll()的线程在调用这些方法前必须"拥有"对象的锁。
		 * 当前的线程不是此对象锁的所有者,却调用该对象的notify(),notify(),wait()方法时抛出该异常。
		 */
		
		Thread thread1 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				try {
					synchronized (o1) {
						
						System.out.println("开始休眠11");
						//大约已经到达指定的实际时间。但是,如果 timeout 为零,则不考虑实际时间,在获得通知前该线程将一直等待。 
						o1.wait(0);// 相当于o1.wait(0);
						System.out.println("唤醒11");
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
		Thread thread2 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				try {
					synchronized (o1) {
						
						System.out.println("开始休眠22");
						o1.wait(1000); 
						System.out.println("唤醒22");
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
		thread1.start();
		thread2.start();
		Thread.sleep(3000);
		synchronized (o1) { 
			//必须用这个对象监视器 monitor 去调用notify, 否则报错java.lang.IllegalMonitorStateException
			System.out.println("调用");
			o1.notify();//随机唤醒一个, 其余的等待
			o1.notifyAll();//唤醒等待池的所有线程, 随机一个线程拿到monitor(即对象监视器, 此处是o1, 如果用o2则没用)
			System.out.println("完毕");
		}
		Thread.sleep(3000);

	}
	
	
	@Test
	public void fun03() throws InterruptedException{
		System.out.println("测试: 是否调用线程进行等待");
		JoinTools jt = new JoinTools();
		jt.startWait(3000);
		System.out.println("调用线程被等待结束");
	}

}

class JoinTools {
	 public final synchronized void startWait(long millis) throws InterruptedException {
            wait(millis);
	 }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值