java笔记--用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程

用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程

 

ThreadLocal在我的笔记"关于线程同步"的第5种方式里面有介绍,这里就不多说了。

 --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3899890.html  "谢谢-- 

Callable<V>接口类似于Runnable,两者都是为了哪些其实例可能被另一个线程执行的类设计的,
但是Runnable不会返回结果,并且无法抛出异常。
在实现此接口的时候,需要重写call()方法:
    V call() throws Exception
   
在本次实例代码中还用到Future<V>接口
    Future<V>接口表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,
    并获取计算的结果。计算完成后只能使用get()方法来获取结果,如有必要计算完成前可以阻塞此方法。
    取消则由cancel方法来执行。
    实现此接口需要重写get()方法:
        V  get() throws InterruptedException,ExecutionException
       
代码实例:
    还是线程同步里面的那个存钱的例子,在这里实现异步计算和线程返回值

package com.xhj.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

/**
 * Runnable接口实现的线程是没有返回值,本实例将运用Callable<V>接口实现一个有返回值的线程应用
 * 
 * @author XIEHEJUN
 * 
 */
public class ReturnValuesToThread {
    private int a = 1;

    class Bank {

        private int account = 100;

        public int getAccount() {
            return account;
        }

        /**
         * 存钱
         * 
         * @param money
         */
        public void save(int money) {
            account += money;
        }

    }

    private class Transfer implements Callable<Integer> {
        private Bank bank;

        public Transfer(Bank bank) {
            this.bank = bank;

        }

        /**
         * 重写call()方法,并执行一个线程
         */
        @Override
        public Integer call() throws Exception {
            int flag = a++;
            System.out.println("启动线程" + flag);
            for (int i = 0; i < 10; i++) {
                bank.save(10);
                System.out.println("账户的余额为:" + bank.getAccount());
            }
            return bank.getAccount();
        }
    }

    /**
     * 建立线程,调用内部类,开始存钱
     */
    public void useThread() {
        /*
         * 这里属于异步操作,故要建立两个Bank对象,倘若只建立一个对象则是对同一个资源进行同步操作,
         * 那么第二线程将会在第一个线程操作完,并释放资源之后才会执行,
         * 但是此时第二个线程得到的本金将不再是最开始初始化的本金而是第一个线程完成操作之后返回的值,而最后的实际金额就是第二个线程的计算结果
         */
        Bank bank1 = new Bank();
        Bank bank2 = new Bank();
        Transfer transfer1 = new Transfer(bank1);
        Transfer transfer2 = new Transfer(bank2);
        FutureTask<Integer> task1 = new FutureTask<Integer>(transfer1);
        FutureTask<Integer> task2 = new FutureTask<Integer>(transfer2);
        Thread thread1 = new Thread(task1);
        Thread thread2 = new Thread(task2);
        thread1.start();
        thread2.start();
        try {
            int threadResult1 = task1.get();
            int threadResult2 = task2.get();
            System.out.println("一号线程的计算结果是 --" + threadResult1);
            System.out.println("二号线程的计算结果是 --" + threadResult2);
            int sum = threadResult1 + threadResult2;
            int count = sum - 100;
            System.out.println("实际金额是 --" + count
                    + " (一号线程的计算结果加上二号线程的计算结果再减去100的本金)");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    public static void main(String[] args) {
        ReturnValuesToThread rethread = new ReturnValuesToThread();
        rethread.useThread();

    }

}

注:在处理有返回值的线程的时候,要记得捕获异常

posted @ 2014-08-08 17:40  Liape  阅读(1858)  评论(1编辑  收藏  举报