编写多线程并发程序分为两步:
1.定义任务;
2.执行任务;
1.定义任务有三种方式
1)实现Runnable接口
1)在main方法创建任务实例调用run()方法执行(非多线程方式)
#0(9),#0(8),#0(7),#0(6),#0(5),#0(4),#0(3),#0(2),#0(1),#0(0),
2)创建单独线程调用start()方法来执行,此时与主线程并行执行
#0(9),#0(8),#0(7),#1(9),#1(8),#1(7),#1(6),#1(5),#1(4),#1(3),#1(2),#1(1),#1(0),
#2(9),#2(8),#2(7),#0(6),#0(5),#3(9),#3(8),#3(7),#3(6),#3(5),#3(4),#3(3),#3(2),
#3(1),#3(0),#0(4),#0(3),#0(2),#0(1),#0(0),#2(6),#2(5),#2(4),#2(3),#2(2),#2(1),
#2(0),Main method is waiting for task execute!#4(9),#4(8),#4(7),#4(6),#4(5),
#4(4),#4(3),#4(2),#4(1),#4(0),
3)Executor的execute方法来执行创建的任务,Executors可以创建不同的三种线程池:
CachedThreadPool:程序执行过程中创建与所需数量相同的线程,首选此线程池;
FixedThreadPool:线程数量固定的线程池;
SingleThreadPool:线程数量为1的线程池;
#0(9),#3(9),Main method is waiting for task execute!
#2(9),#1(9),#2(8),#3(8),#4(9),#0(8),#4(8),#3(7),#2(7),#2(6),#2(5),#2(4),#1(8),
#2(3),#3(6),#4(7),#0(7),#4(6),#3(5),#2(2),#1(7),#2(1),#3(4),#4(5),#0(6),#4(4),
#3(3),#2(0),#1(6),#1(5),#1(4),#1(3),#1(2),#1(1),#1(0),#3(2),#3(1),#3(0),#4(3),
#4(2),#4(1),#4(0),#0(5),#0(4),#0(3),#0(2),#0(1),#0(0),
1.定义任务;
2.执行任务;
1.定义任务有三种方式
1)实现Runnable接口
class Task implements Runnable{
private int countDown=10;
static int taskCount=0;
private int id=taskCount++;
private void printStatus(){
System.out.print("#"+id+"("+countDown+"),");
}
public void run(){
while(countDown-->0){
printStatus();
}
}
}
2)继承Thread,覆写run()方法
class Task extends Thread{
private int countDown=10;
static int taskCount=0;
private int id=taskCount++;
private void printStatus(){
System.out.print("#"+id+"("+countDown+"),");
}
public void run(){
while(countDown-->0){
printStatus();
}
}
}
3)实现Callable接口(适用于带有返回参数的任务),Call是一个泛型接口,类型参数表示的是从call()返回的参数类型,使用ExecutorService.submit()方法调用,返回的是Future<T>对象
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorTask {
public static void main(String[] args) {
ExecutorService exec=Executors.newCachedThreadPool();
for(int i=0;i<5;i++){
exec.execute(new Task3());
}
exec.shutdown();
System.out.println("Main method is waiting for task execute!");
}
}
class Task3 extends Thread{
private int countDown=10;
static int taskCount=0;
private int id=taskCount++;
private void printStatus(){
System.out.print("#"+id+"("+countDown+"),");
}
public void run(){
while(countDown-->0){
printStatus();
}
}
}
2.执行任务有三种方式
1)在main方法创建任务实例调用run()方法执行(非多线程方式)
public class RunnableTask {
public static void main(String[] args) {
Task task=new Task();
task.run();
}
}
输出:
#0(9),#0(8),#0(7),#0(6),#0(5),#0(4),#0(3),#0(2),#0(1),#0(0),
2)创建单独线程调用start()方法来执行,此时与主线程并行执行
public class ThreadTask {
public static void main(String[] args) {
for(int i=0;i<5;i++){
new Thread(new Task()).start();
}
System.out.println("Main method is waiting for task execute!");
}
}
输出:
#0(9),#0(8),#0(7),#1(9),#1(8),#1(7),#1(6),#1(5),#1(4),#1(3),#1(2),#1(1),#1(0),
#2(9),#2(8),#2(7),#0(6),#0(5),#3(9),#3(8),#3(7),#3(6),#3(5),#3(4),#3(3),#3(2),
#3(1),#3(0),#0(4),#0(3),#0(2),#0(1),#0(0),#2(6),#2(5),#2(4),#2(3),#2(2),#2(1),
#2(0),Main method is waiting for task execute!#4(9),#4(8),#4(7),#4(6),#4(5),
#4(4),#4(3),#4(2),#4(1),#4(0),
3)Executor的execute方法来执行创建的任务,Executors可以创建不同的三种线程池:
CachedThreadPool:程序执行过程中创建与所需数量相同的线程,首选此线程池;
FixedThreadPool:线程数量固定的线程池;
SingleThreadPool:线程数量为1的线程池;
public class ExecutorTask {
public static void main(String[] args) {
ExecutorService exec=Executors.newCachedThreadPool();
for(int i=0;i<5;i++){
exec.execute(new Task());
}
System.out.println("Main method is waiting for task execute!");
}
}
输出:
#0(9),#3(9),Main method is waiting for task execute!
#2(9),#1(9),#2(8),#3(8),#4(9),#0(8),#4(8),#3(7),#2(7),#2(6),#2(5),#2(4),#1(8),
#2(3),#3(6),#4(7),#0(7),#4(6),#3(5),#2(2),#1(7),#2(1),#3(4),#4(5),#0(6),#4(4),
#3(3),#2(0),#1(6),#1(5),#1(4),#1(3),#1(2),#1(1),#1(0),#3(2),#3(1),#3(0),#4(3),
#4(2),#4(1),#4(0),#0(5),#0(4),#0(3),#0(2),#0(1),#0(0),