java thread 并行处理

package com.yuan.test;

public class LiftOff implements Runnable {
	 protected int countDown = 10; // Default
	 private static int taskCount = 0;
	 private final int id = taskCount++;
	 public LiftOff() {}
	 public LiftOff(int countDown) {
	 this.countDown = countDown;
	 }
	 public String status() {
	 return "#" + id + "(" +
	 (countDown > 0 ? countDown : "Liftoff!") + "), ";
	 }
	 public void run() {
	 while(countDown-- > 0) {
	 System.out.print(status());
	 Thread.yield();
	 }
	 }
	 public static void main(String[] args){
		 LiftOff lo=new LiftOff();
		 lo.status();
		 lo.run();
		 LiftOff lo1=new LiftOff();
		 lo1.status();
		 lo1.run();
		 
	 }
	} ///:~

每一个需要并行处理的任务都需要实现Runable接口。

The identifier id distinguishes between multiple instances of the task. It is final because it is
not expected to change once it is initialized.

上述ID 是用来区分线程的个数的,而且因为它是final 类型的所以一旦实例化了就不会被修改了。
A task’s run( ) method usually has some kind of loop that continues until the task is no
longer necessary, so you must establish the condition on which to break out of this loop (one
option is to simply return from run( )). 

Often, run( ) is cast in the form of an infinite loop,which means that, barring some factor that causes run( ) to terminate, it will continue forever (later in the chapter you’ll see how to safely terminate tasks).

The call to the static method Thread.yield( ) inside run( ) is a suggestion to the thread
scheduler (the part of the Java threading mechanism that moves the CPU from one thread to
the next) that says,

1、Thread.yields()

Thread.yields()是一个静态的方法,用来给CPU提一下建议说,“您已经帮我完成最重要的工作了,你要是忙,你就先走吧”

 "I’ve done the important parts of my cycle and this would be a good time
to switch to another task for a while."

 It’s completely optional, but it is used here because it tends to produce more interesting output in these examples: You’re more likely to see evidence of tasks being swapped in and out.

public class TestThread {

	public static void main(String[] args) {
		 Thread t = new Thread(new LiftOff());
		 t.start();
		 System.out.println("Waiting for LiftOff1");
		 Thread t1 = new Thread(new LiftOff());
		 t1.start();
		 System.out.println("Waiting for LiftOff2");
	}

}

通过将实现了Runable接口的任务作为参数来实例化线程。

output:

Waiting for LiftOff1

Waiting for LiftOff2

#1(9), #0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(Liftoff!), #1(8), #1(7), #1(6), #1(5), #1(4), #1(3), #1(2), #1(1), #1(Liftoff!), 

通过观察输出结果可以看出,两个线程是随机执行的。

When main( ) creates the Thread objects, it isn’t capturing the references for any of them.
With an ordinary object, this would make it fair game for garbage collection, but not with a
Thread. Each Thread "registers" itself so there is actually a reference to it someplace, and
the garbage collector can’t clean it up until the task exits its run( ) and dies. You can see
from the output that the tasks are indeed running to conclusion, so a thread creates a
separate thread of execution that persists after the call to start( ) completes.

下面还有一种使用并行处理线程的方法:通过引入ExecutorService和Executors 来并行处理线程。其中

ExecutorService 是通过Executors的静态方法来实例化的。

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

import org.apache.log4j.lf5.LF5Appender;

public class TestThread {

	public static void main(String[] args) {
			 ExecutorService exec = Executors.newCachedThreadPool();
			 // Constructor argument is number of threads:可以固定初始化线程的数//目
                          ExecutorService exec = Executors.newFixedThreadPool(5);
			 for(int i = 0; i < 5; i++)
			 exec.execute(new LiftOff());
			 exec.shutdown();
	}

}

2、关于CachedThreadPools和FixedThreadPools的一点说明。

Note that in any of the thread pools, existing threads are automatically reused when possible.

线程池里面的线程都是可以再利用的。
Although this book will use CachedThreadPools, consider using FixedThreadPools in
production code. 

A CachedThreadPool will generally create as many threads as it needs
during the execution of a program and then will stop creating new threads as it recycles the
old ones, so it’s a reasonable first choice as an Executor

CachedThreadPool将会持续不断生成threads,直到有可以再利用的线程,所以这种方法似乎是比较合理的。

Only if this approach causes
problems do you need to switch to a FixedThreadPool.

如果你发现CatchedThreadPool会产生问题,那么你要想想用FixedThreadPool.

3、newSingleThreadExecutor

public class TestThread {

	public static void main(String[] args) {
			 ExecutorService exec = Executors.newSingleThreadExecutor();
			 for(int i = 0; i < 5; i++)
			 exec.execute(new LiftOff());
			 exec.shutdown();
	}

}

说明:值实例化了一个线程,如果还有其它的任务,这些任务就进入了队列。等待被执行,从输出的结果来看,是按照顺序执行的。

output:

#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(Liftoff!), #1(9), #1(8), #1(7), #1(6), #1(5), #1(4), #1(3), #1(2), #1(1), #1(Liftoff!), #2(9), #2(8), #2(7), #2(6), #2(5), #2(4), #2(3), #2(2), #2(1), #2(Liftoff!), #3(9), #3(8), #3(7), #3(6), #3(5), #3(4), #3(3), #3(2), #3(1), #3(Liftoff!), #4(9), #4(8), #4(7), #4(6), #4(5), #4(4), #4(3), #4(2), #4(1), #4(Liftoff!), 


你可能感兴趣的:(java,thread,并行处理,构造方法以及runable接口)