【多线程_basic】 Java多线程回顾与复习

好久没用多线程了,复习一下~~

1.几种调用多线程的方式(部分源码摘自 《Thinking in Java》)

①:实现Runnable接口,见下面例子:

class LiftOff implements Runnable{
	
	protected int countDown=10;
	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")+")";
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(countDown-- >0){
			System.out.println(status());
			Thread.yield();
		}
	}
}

public class method1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		LiftOff launch = new LiftOff(10);
		launch.run();
	}

}

注意,这里 启动线程采用的run()函数

2.Thread类:或者继承Thread类

public class methdo2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Thread thread = new Thread(new LiftOff());
		thread.start();
	}

}

这里的Thread的构造函数需要传入一个实现了Runnable接口的对象,他启动 线程采用start()函数

3.Executor

public class method3 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ExecutorService exe = Executors.newCachedThreadPool();
		for(int i=0;i<5;i++){
			exe.execute(new LiftOff());
		}
		exe.shutdown();
	}

}

exe.execute()里面传入一个实现了runnable()接口的类,并且执行~ 它启动线程的方式为execute();

对于Executor的创建,主要有以下三种:
newcachedThreadPool:可扩充线程数量的线程池
newFixedThreadPool:创建固定数量线程的线程池
newSingleThreadExecutor:单线程

4.实现Callable接口;

Callable接口是一种具有类型参数的泛型,它的类型参数表示是从方法call()中返回的【注意不是run()】,并且使用ExecutorService.submit()方法调用它

class TaskWithResult implements Callable<String>{
	private int id;
	public TaskWithResult(int id){
		this.id=id;
	}
	@Override
	public String call() throws Exception {
		// TODO Auto-generated method stub
		return "result of TaskWithResult "+id;
	}
}

public class method4 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ExecutorService exec = Executors.newCachedThreadPool();
		ArrayList<Future<String>> result =new ArrayList<Future<String>>();
		for(int i=0;i<10;i++){
			result.add(exec.submit(new TaskWithResult(i)));
		}
		for(Future<String> fs:result){
			try {
				System.out.println(fs.get());
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ExecutionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				exec.shutdown();
			}
		}
	}
	
	
}
submit方法会产生Future对象。

如题调用多线程就以上四种方式~


2.守护线程和普通线程

守护线程是在程序运行的时候在后台提供一种通用服务的线程。它可以缺省~

它与普通线程的区别有以下几点:

①:创建:要设置守护线程,必须要在启动之前设置为setDaemon()方法,而普通线程不需要这一步。
②:守护线程创建的任何线程都是守护线程;而普通线程都可以创建。
③:守护线程不会执行finally里面的语句;普通线程会执行。
④:程序要在普通线程运行完才会终止;但是却不会等守护线程运行完:即如果main函数执行完,无论守护线程是否执行完都会终止。


3.多线程里面的几个关键字

①join:如果线程A在线程B中上调用A.join,A线程挂起,等线程B执行完~ 

class Sleeper extends Thread{
	private int duration;
	public Sleeper(String name,int sleepTime){
		super(name);
		duration=sleepTime;
		start();
	}
		
	public void run() {
		try {
			sleep(duration);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println(getName()+" was interrupted."+" isInterrupted " +isInterrupted());
		}
		System.out.println("awakend");
	}
}

class Joiner extends Thread{
	private Sleeper sleeper;
	public Joiner(String name,Sleeper sleeper){
		super(name);
		this.sleeper=sleeper;
		start();
	}
	
	public void run(){
		try {
			sleeper.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println("interrupted..");
		}
		System.out.println(getName()+" join complete..");
	}
}

public class join {
	public static void main(String[] args){
		Sleeper s = new Sleeper("sleeper",1500);
		Joiner j = new Joiner("joiner", s);
	
	}
}

输出结果肯定是:先执行完Sleeper中的,在执行joiner中的~,结果如下:

awakend
joiner join complete..

如果没有join的话,即如果如下:

joiner join complete..
awakend

②:interrupt:将该线程设定一个标志,表示该线程已经被打断。

还是上面的例子:只改最后一个类

public class join {
	public static void main(String[] args){
		Sleeper s = new Sleeper("sleeper",1500);
		Joiner j = new Joiner("joiner", s);
		s.interrupt();
	}
}


我们可以看到输出:

sleeper was interrupted. isInterrupted false
awakend
joiner join complete..


分析下:由于要等到sleeper运行完才能运行joiner,此时我们设置了中断,进入catch块;进入catch块后,异常被捕获之后将清理这个标志,所以我们发现isInterrupt()函数为false;




23.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值