JAVA学习笔记——并发(一)

java中的并发实际上是多线程,要实现并发,需要实现Runnable接口并编写run()方法。下面循序渐进地给出多种运行线程的方法。

1. 直接运行类的方法

新建一个类实现Runnable接口并编写run()方法,然后实例这个类调用其run()方法。
这种方法其实不会启动新的线程,还是只有一个线程,即分配给main()的那个线程。Runnable接口的run方法没有特殊之处,调用这个任务的run方法不会启动新的线程,要启动新的线程,需要显式地将任务分配给线程。

public class test1 implements Runnable {
    private int cnt = 5;
    @Override
    public void run() {
        while (cnt-- > 0) {
            System.out.println(cnt);
        }
    }

    public static void main(String[] args) {
        test1 temp = new test1();
        temp.run();
    }
}

2. 使用Thread类

我们引入Thread类,将任务test1装进Thread,在t.start()之后,新的一个线程启动,main()所在的线程和t线程共同运行。

public class test1 implements Runnable {
    private int cnt = 5;
    @Override
    public void run() {
        while (cnt-- > 0) {
            System.out.println(cnt);
        }
    }

    public static void main(String[] args) {
        for(int i = 0; i < 5; i++) {
            new Thread(new test1()).start();
        }
    }
}

3. 使用ExecutorService类

在java5中,并发包java.util.concurrent内新增了Executor,用来管理线程,简化了并发编程。

3.1 使用newCachedThreadPool()方法

使用newCachedThreadPool()方法,在每次execute()之后,线程开始被创建并运行。 在shutdown()之前,都可以调用execute()向管理器提交线程。

public class test1 implements Runnable {
    private int cnt = 5;
    @Override
    public void run() {
        while (cnt-- > 0) {
            System.out.println(cnt);
        }
    }

    public static void main(String[] args) {
        ExecutorService exec = Executors.newCachedThreadPool();
        for(int i = 0; i < 5; i++) {
            exec.execute(new test1());
        }
        exec.shutdown();
    }
}

3.2 使用newFixedThreadPool(int)方法

使用newFixedThreadPool(int)方法,线程提前被创建,一次性预先执行高昂代价的线程创建。

public class test1 implements Runnable {
    private int cnt = 5;
    @Override
    public void run() {
        while (cnt-- > 0) {
            System.out.println(cnt);
        }
    }

    public static void main(String[] args) {
        try {
            ExecutorService exec = Executors.newFixedThreadPool(5);
            for (int i = 0; i < 5; i++) {
                exec.execute(new test1());
            }
            TimeUnit.MILLISECONDS.sleep(500);
            exec.shutdown();
        }catch (InterruptedException e){

        }
    }
}

3.3 使用newSingleThreadExecutor()方法

在这种情况下,所有任务按照它们被提交的顺序串行执行,且被分配到同一个线程。

public class test1 implements Runnable {
    private int cnt = 5;
    @Override
    public void run() {
        while (cnt-- > 0) {
            System.out.println(cnt);
        }
    }

    public static void main(String[] args) {
        ExecutorService exec = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 5; i++) {
            exec.execute(new test1());
        }
        exec.shutdown();
    }
}

4. 有返回值的任务

Runnable接口的run()方法没有返回值。如果我们需要在其结束后,能产生返回值的线程,就需要使用Callable接口。应该提交线程给执行器的时候,应该使用submit()方法,该方法返回Future对象。

public class test2 implements Callable<String> {
    private int cnt = 2;

    public String call() {
        while (cnt-- > 0) {
            System.out.println(cnt);
        }
        return "pxz";
    }

    public static void main(String[] args) {
        ExecutorService exec = Executors.newSingleThreadExecutor();
        Future<String> fs = exec.submit(new test2());
        exec.shutdown();

        try {//Future对象需要捕获以下两个异常
            System.out.println(fs.get());
        }catch (InterruptedException e){

        }
        catch (ExecutionException e){
            
        }

    }
}
posted @ 2017-06-09 10:02  水煮海鲜  阅读(184)  评论(0编辑  收藏  举报