2021-04-03

并发(1)创建线程

简述:

Web系统是最常见的java应用系统之一,基本的Web库类,servlet具有天生的多线程性。

并发解决的问题大体上分为"速度",和“设计可管理性”两种。

反常识的是并发通常提高运行在单处理器上的程序的性能。在上下文切换上的开销会很大,但单处理器可能会因为程序控制之外的原因(通常是I/O)导致阻塞。并发此时就可以显著提升性能。没有阻塞,单处理器上就不需要并发了。在单处理器系统中的性能提高常见示例是事件驱动的编程。(某些编程语言被设计为可以将并发任务彼此隔离,这些语言通常被称为函数式语言,每个函数调用都不会产生任何副作用因此也不能干涉其他函数,比如Erlang,他包含针对任务之间彼此通讯的安全机制。如果程序中某个部分必须大量使用并发,可以使用它

前几天被人说并发不行,特复习一遍老知识。

创建任务:

public 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.print(status());
			Thread.yield();//切换下一个进程
		}
		System.out.println("=======结束=======");
	}
	
	public static void main(String[] args) {
		//直接运行runnable
//		LiftOff launch = new LiftOff();
//		launch.run();	
		
		//通过thread运行
//		Thread t = new Thread(new LiftOff());
//		t.start();
//		System.out.println("waiting fot LiftOff");
		
		
		/*
		 * 运行5条线程
		 * jdk会切换时间片   
		 */
//		for(int i=0;i<5 ; i++) {
//			new Thread(new LiftOff()).start();
//		}
//		System.out.println("wait for LiftOff");
		
		
		//通过线程池管理线程 (会创建和所需数量相同的线程)
//		ExecutorService c_exec = Executors.newCachedThreadPool();
//		for(int i=0 ; i<5 ; i++) {
//			c_exec.execute(new LiftOff());
//		}
//		c_exec.shutdown();
//		System.out.println("finish");
		
		
		//通过线程池管理线程(会创建固定的线程)
//		ExecutorService f_exec = Executors.newFixedThreadPool(5);
//		for(int i=0 ; i<6 ; i++) {
//			f_exec.execute(new LiftOff());
//		}
//		f_exec.shutdown();
//		System.out.println("finish");
		
		//会创建一个线程来连续运行任务,这些任务会排队,每一个任务结束再继续新任务(通常是长期存活的任务)
		ExecutorService s_exec = Executors.newSingleThreadExecutor();
		for(int i=0 ; i<6 ; i++) {
			s_exec.execute(new LiftOff());
		}
		s_exec.shutdown();
		System.out.println("finish");
		
	}
}

 

Runnable是无返回值的,如果需要了解线程在运行中的状态可以实现Callable,使用ExecutorService.submit()方法调用:

创建有返回值的任务:


public 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
//		Thread.sleep(2000);
		System.out.println("do_task");
		return "result of TaskWithResult"+id;
	}
	
	public static void main(String[] args) {
		ExecutorService exec = Executors.newCachedThreadPool();
		ArrayList<Future<String>> results = new ArrayList<Future<String>>();
		for(int i = 0 ; i<=5 ; i++) {
			results.add(exec.submit(new TaskWithResult(i)));
		}
		for(Future<String> fs : results) {
			try {
				System.out.println(fs.isDone());//是否完成
				System.out.println(fs.get());
			} catch (InterruptedException | ExecutionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally {
				exec.shutdown();
			}
		}
	}
}

使用内部类创建任务

public class ThreadVariations {
	class InnerThread1 {
		private int countDown = 5;
		private Inner inner;
		private class Inner extends Thread{
			Inner(String name){
				super(name);
				start();
			}
			public void run() {
				try {
					while(true) {
						System.out.println(this);
						if(--countDown==0)return;
						sleep(10);
					}
				} catch (Exception e) {
					// TODO: handle exception
					System.out.println("interrupted");
				}
			}
			public String toString() {
				return getName() + ": "+countDown;
			}
		}
		public InnerThread1(String name) {
			inner = new Inner(name);
		}
	}
	
	
	class InnerThread2{
		private int countDown = 5;
		private Thread t;
		public InnerThread2(String name) {
			t = new Thread(name) {
				public void run() {
					try {
						while(true) {
							System.out.println(this);
							if(--countDown==0)return;
							sleep(10);
						}
					} catch (Exception e) {
						System.out.println("interrupted");
					}
				}
				public String toString() {
					return getName() + ": "+countDown;
				}
			};
			t.start();
		}
	}
	
	
	class InnerRunnable1{
		private int countDown = 5;
		private Inner inner;
		private class Inner implements Runnable{
			public Thread t;
			public Inner(String name) {
				t = new Thread(this,name);
				t.start();
			}
			public void run() {
				try {
					while(true) {
						System.out.println(this);
						if(--countDown==0)return;
						t.sleep(10);
					}
				} catch (Exception e) {
					// TODO: handle exception
					System.out.println("interrupted");
				}
			}
			public String toString() {
				return t.getName() + ": "+countDown;
			}
		}
		public InnerRunnable1(String name) {
			inner = new Inner(name);
		}
	}
	
	
	class InnerRunnable2{
		private int countDown = 5;
		private Thread t;
		public InnerRunnable2(String name) {
			t = new Thread( new Runnable(){
				public void run() {
					try {
						while(true) {
							System.out.println(this);
							if(--countDown==0)return;
							t.sleep(10);
						}
					} catch (Exception e) {
						System.out.println("interrupted");
					}
				}
				public String toString() {
					return t.getName() + ": "+countDown;
				}
			},name);
			t.start();
		}
	}
	
	class ThreadMethod{
		private int countDown = 5;
		private Thread t;
		private String name;
		public ThreadMethod(String name){this.name = name;}
		public void runTask(){
			if(t==null){
				t = new Thread(name){
					public void run(){
						try {
						while(true) {
							System.out.println(this);
							if(--countDown==0)return;
							t.sleep(10);
							}
						} catch (Exception e) {
							System.out.println("interrupted");
						}
					}
					public String toString() {
						return t.getName() + ": "+countDown;
					}
				};
				t.start();
			}
		}
	}
	
	public static void main(String[] args) {
		ThreadVariations t = new ThreadVariations();
		t.new InnerThread1("InnerThread1");
		t.new InnerThread2("InnerThread2");
		t.new InnerRunnable1("InnerRunnable1");
		t.new InnerRunnable2("InnerRunnable2");
		t.new ThreadMethod("threadMethod").runTask();
		
	}
}

线程的异常传递到main方法需要特别处理


/* 
 * 线程的异常一旦跳出run()方法,并传递到main方法就无法使用try catch来捕获
 * 需要使用UncaughtExceptionHandler来捕获
 */

public class CaptureUncaughtException {
	public static void main(String[] args) {
		ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFactory());
		exec.execute(new ExceptionThread2());
		
	}
}


class ExceptionThread2 implements Runnable{
	@Override
	public void run() {
		// TODO Auto-generated method stub
		Thread t = Thread.currentThread();
		System.out.println("run:"+t);
		System.out.println("eh = "+t.getUncaughtExceptionHandler());
		throw new RuntimeException();
	}
}


class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{
	@Override
	public void uncaughtException(Thread t, Throwable e) {
		// TODO Auto-generated method stub
		System.out.println("caught"+e);
	}
}

class HandlerThreadFactory implements ThreadFactory{
	@Override
	public Thread newThread(Runnable r) {
		System.out.println(this +"creating new Thread");
		Thread t = new Thread(r);
		System.out.println("crteated "+t);
		t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
		System.out.println("eh= "+t.getUncaughtExceptionHandler());
		return t;
	}
}

休眠:Thread.currentThread().sleep(2000);,TimeUnit.MILLISECONDS.sleep(2000);

优先级:Thread.currentThread().setPriority(priority);//不常用

(设置优先级 每个系统的优先级不一样。并且线程也不一定按照优先级来运行。)

让步:Thread.yield();//不常用

(设置让步也是不一定的,只是给线程调度机制一个暗示)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值