并发(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();//不常用
(设置让步也是不一定的,只是给线程调度机制一个暗示)