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();

    }

}

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

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

时间: 2024-08-05 19:30:06

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

Java线程:线程安全类和Callable与Future(有返回值的线程)

一.线程安全类 当一个类已经很好的同步以保护它的数据时,这个类就称为线程安全的.当一个集合是安全的,有两个线程在操作同一个集合对象,当第一个线程查询集合非空后,删除集合中所有元素的时候,第二个线程也来执行与第一个线程相同的操作,也许第一个线程查询后,第二个也查出非空,但是此时明显是不对的.如: 1 public class NameList { 2 private List nameList = Collections.synchronizedList(new LinkedList()); 3

Java Callable接口——有返回值的线程

实际开发过程中,我们常常需要等待一批线程都返回结果后,才能继续执行.<线程等待--CountDownLatch使用>中我们介绍了CountDownLatch的使用,通过使用CountDownLatch,可以实现线程等待. JDK 1.8实现了一种更好的方式,实现线程等待与获取线程返回值,那就是Callable接口,下面我们来看看具体代码. package com.coshaho.learn; import java.util.Random; import java.util.concurren

线程池, Callable&lt;V&gt;接口

线程池: 概念:线程池,其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源. Executors:线程池创建工厂类 ExecutorService:线程池类 ExecutorService er=Executors.newFixedThreadPool(int);返回线程池对象 submit()获取线程池中的某一个线程对象,并执行线程中的call()方法 shutdown();释放资源 例: //获取线程池对象 ExecutorS

Java线程:新特征-有返回值的线程

http://lavasoft.blog.51cto.com/62575/222082/ 2009-11-04 17:33:56 标签:返回值 职场 线程 休闲 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://lavasoft.blog.51cto.com/62575/222082 Java线程:新特征-有返回值的线程 在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,

Java线程:新特征-有返回值的线程《转》

原始文章 在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了. 现在Java终于有可返回值的任务(也可以叫做线程)了. 可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口. 执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了. 下面是个很简单的例子: import java.util.concurrent.*

Querying Microsoft SQL Server 2012 读书笔记:查询和管理XML数据 1 -使用FOR XML返回XML结果集

原文:Querying Microsoft SQL Server 2012 读书笔记:查询和管理XML数据 1 -使用FOR XML返回XML结果集 XML 介绍 <CustomersOrders> <Customer custid="1" companyname="Customer NRZBB"> <Order orderid="10692" orderdate="2007-10-03T00:00:00&

Thead线程篇之-----多线程 实现 有返回值的功能

import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class MyCallBack implements Callable<String>{ private String threadName; public MyCallBack() { } public MyCallBack(S

带返回值的线程

创建一个线程有几种方式,很容易想到的就是集成Thread类,实现Runnable接口,还有一种方式就是自己定义的线程类实现Callable接口,这种方式相较于实现Runnable接口具有带有返回值的特点,大家都知道在java中主线程中创建的线程可以独立于主线程执行,也就是说main函数结束了.在main函数中产生的线程还在继续执行,如果希望主线程在所有子线程都结束再结束,该怎么做呢?可以试想这样一种场景:创建了50个线程,每个线程计算10000个数字之和,最后计算出总和.如果线程继承了Runna

工作随笔——Java调用Groovy类的方法、传递参数和获取返回值

接触Groovy也快一年了,一直在尝试怎么将Groovy引用到日常工作中来.最近在做一个功能的时候,花了点时间重新看了下Java怎么调用Groovy的方法.传递参数和获取返回值. 示例Groovy代码如下: # TestGroovy.groovy 定义testC方法,传入3个参数,返回处理后的数据 def testC(int numA, int numB, int numC) { "传入参数:" + numA + numB + numC + "计算之和为:" + (