Java多线程基础知识(三)

一. 管道输入/输出流

它和其它文件输入/输出流或网络输入/输出流的不同之处,它主要是线程之间的数据传输,而传输的媒介是内存。

管道输入/输出流主要包含四中实现:

1. PipedOutputStream, PipedInputStream 面向字节

2. PipedWriter, PipedReader 面向字符

对于Piped类型的流,必须向要进行绑定,需要调用connect()方法,如果没有将输入输出流绑定起来,对于该流的访问会报异常。

package com.bochao.concurrent;

import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;

public class Piped {

	static class Print implements Runnable {

		private PipedReader in;

		public Print(PipedReader in) {
			this.in = in;
		}

		@Override
		public void run() {
			int receive = 0;
			try {
				while ((receive = in.read()) != -1) {
					System.out.print((char)receive);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {

		PipedWriter pipedWriter = new PipedWriter();
		PipedReader pipedReader = new PipedReader();
		try {
			pipedWriter.connect(pipedReader);
		} catch (IOException e) {
			e.printStackTrace();
		}

		// 启动打印线程
		Thread thread = new Thread(new Print(pipedReader), "PrintThread");
		thread.start();

		//
		int receive = 0;
		try {
			while ((receive = System.in.read()) != -1) {
				pipedWriter.write(receive);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				pipedWriter.close();
				pipedReader.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}
}

二. Thread.join的使用

假设一个线程A调用了thread.join语句,其含义时当前线程A等待thread线程终止之后才从thread.join返回。

package com.bochao.concurrent;

import java.util.concurrent.TimeUnit;

public class Join {
	
	static class Domino implements Runnable{
		
		private Thread thread;
		
		public Domino(Thread thread){
			this.thread = thread;
		}

		@Override
		public void run() {
			
			try {
				thread.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + " terminate.");
		}
	}

	
	public static void main(String[] args) throws InterruptedException {
		
		Thread previous = Thread.currentThread();
		for(int i = 0; i<10; i++){
			Thread thread = new Thread(new Domino(previous), String.valueOf(i));
			thread.start();
			// 接力
			previous = thread;
		}
		TimeUnit.SECONDS.sleep(5);
		System.out.println(Thread.currentThread().getName() + " terminate.");
	}
}


三. ThreadLocal 的使用

即线程变量,是一个以ThreadLocal对象为键,任意对象为值得存储结构。这个对象被附带在线程上,也就是说一个线程可以根据一个ThreadLocal对象查询到绑定在这个线程上的一个值。

通过set(T) 设置一个值,在通过get()方法获取到原先设置的值。


package com.bochao.concurrent;

import java.util.concurrent.TimeUnit;

public class Profiler {
	
	// 第一次get()方法调用时会进行初始化(如果set()方法没有调用),每个线程会调用一次
	private static final ThreadLocal<Long> TIME_THREADLOCAL = new ThreadLocal<Long>(){

		@Override
		protected Long initialValue() {
			return System.currentTimeMillis();
		}
	};
	
	public static final void begin(){
		TIME_THREADLOCAL.set(System.currentTimeMillis());
	}
	
	public static final long end(){
		return System.currentTimeMillis() - TIME_THREADLOCAL.get();
	}
	
	public static void main(String[] args) throws InterruptedException {
		Profiler.begin();
		TimeUnit.SECONDS.sleep(2);
		System.out.println("Cost: " + Profiler.end() + " mills!");
	}
	
}


你可能感兴趣的:(Java多线程基础知识(三))