Java并发总结一 :1~2

来源:互联网 发布:斯提亚在淘宝的正品店 编辑:程序博客网 时间:2024/05/16 18:40

1.并发多面性

多处理器的web服务器:为每个请求分配一个线程。
单处理器:用户界面,创建单独线程来响应用户输入
仿真:动画中,解决大量的独立动作

2.基本线程机制

底层机制:切分CPU时间,每个线程都觉得自己一直在占用CPU时间

2.1 定义任务

继承runnable接口,并覆盖run方法

public class MyTask implements Runnable{    @Override    public void run() {        for (int i = 0; i < 3; i++) {            System.out.println(Thread.currentThread().getId());            Thread.yield();        }    }}

2.2 使用Thread类创建线程

//使用构造方法传入2.1中任务Thread thread=new Thread(new MyTask());

2.3 使用Executors类的静态方法创建线程

ExecutorService service1=Executors.newCachedThreadPool();ExecutorService service2=Executors.newFixedThreadPool(45);ExecutorService service3=Executors.newSingleThreadExecutor();ExecutorService service4=Executors.newScheduledThreadPool(56);
  • newCachedThreadPool
    创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
  • newFixedThreadPool
    创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
  • newSingleThreadExecutor
    创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
  • newScheduledThreadPool
    创建一个定长线程池,支持定时及周期性任务执行。

线程池的作用:

限制系统中执行线程的数量 ,可以自动或手动设置线程数量,达到运行的最佳效果;
少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了;否则进入等待队列。

2.4 从任务中产生返回值

继承Callable接口。

class MyReturnTask implements Callable<String> {    @Override    public String call() throws Exception {        return "some...strings";    }}

使用ExecutorService实例的submit()方法调用它。

ExecutorService e = Executors.newFixedThreadPool(10);Future<String> future = e.submit(new MyReturnTask());while (true) {   if (future.isDone()) {        System.out.println(future.get());        break;   }}e.shutdown();

submit()方法返回一个Future,isDone()会检查Future是否完成。
你也可以直接调用Future的get方法,它具有阻塞作用,知道完成才会获取值。

2.5 线程休眠

第一种方式:使用Thread.sleep(n) —>可读性较差

Thread.sleep(1000);

第二种方式:使用TimeUnit类—>推荐

TimeUnit.SECONDS.sleep(3);//休眠3秒TimeUnit.MINUTES.sleep(5);//休眠5分钟TimeUnit.DAYS.sleep(8);//休眠8天

2.6 优先级

public class MyTask implements Runnable {    @Override    public void run() {        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);//最高优先级        Thread.currentThread().setPriority(Thread.MIN_PRIORITY);//最低优先级        Thread.currentThread().setPriority(Thread.NORM_PRIORITY);//中等优先级        Thread.currentThread().setPriority(8);//优先级为8        Thread.currentThread().getPriority();// 获取 当前优先级    }}

2.7 让步

建议具有相同优先级的其他程序可以运行。

Thread.yield();

2.8 后台线程

使用Thread.setDeamon

如下,主线程退出后,后台线程也会退出,如果去掉thread.setDaemon(true)这句时,该线程将会一直循环打印下去…

public class RunTest {    public static void main(String[] args) throws InterruptedException {        Thread thread = new Thread(new MyDeamonTask());        thread.setDaemon(true);//尝试下去掉这句        thread.start();        TimeUnit.MILLISECONDS.sleep(15);        //主线程退出    }}class MyDeamonTask implements Runnable {    @Override    public void run() {        while (true) {            System.out.println(Thread.currentThread());        }    }}

使用ThreadFactory

class MyFactory implements ThreadFactory {    @Override    public Thread newThread(Runnable r) {        Thread t = new Thread(r);        t.setDaemon(true);//此处也可以对进程进行其他设置,比如优先级        return t;    }}public class RunTest {    public static void main(String[] args) throws InterruptedException {        ExecutorService service = Executors.newCachedThreadPool(new MyFactory());        service.execute(new Runnable() {            @Override            public void run() {                while (true){                    System.out.println(Thread.currentThread().getId()+"deamon");                }            }        });        TimeUnit.MILLISECONDS.sleep(123);        //主线程退出    }}

后台线程派生出来的线程也是后台线程

2.9直接使用Thread创建线程和任务

继承Thread类并覆盖run方法即可

class MyThread extends Thread{    @Override    public void run() {        //do     }}

2.10 加入一个线程

public class RunTest {    public static void main(String[] args) throws InterruptedException {        Thread t = new MyThread();        t.start();        t.join();//main线程被挂起,直到t线程结束        System.out.println("main..."  );    }}class MyThread extends Thread {    @Override    public void run() {        for (int i = 0; i < 10; i++) {            System.out.println(i);            try {                TimeUnit.MILLISECONDS.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}

上述代码执行 结果如下:

如果去掉t.join(),会发现main线程将不会最后执行!

2.11 线程的异常

代码如下:主线程将不会捕获到MyThread中出现的异常

public class RunTest {    public static void main(String[] args) throws InterruptedException {        Thread t = new MyThread();        try{            t.start();        }catch (Exception e){            System.out.println("catch it");        }    }}class MyThread extends Thread {    @Override    public void run() {         throw new RuntimeException("exception~~~");    }}

使用setUncaughtExceptionHandler,修改为:

public class RunTest {    public static void main(String[] args) throws InterruptedException {        Thread t = new MyThread();        t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {            @Override            public void uncaughtException(Thread t, Throwable e) {                System.out.println("catch it...");            }        });        t.start();    }}

0 0
原创粉丝点击