多线程学习之创建线程

多线程

创建线程的方法有两种-一种是通过继承Thread类,另一种是通过实现Runnable创建线程。

实现Runnable接口

1】定义Runnable接口的实现类,重写run()方法,这个run()方法和Thread中的run()方法一样是线程的执行体
2】创建Runnable实现类的实例,并用这个实例作为Thread的target来创建Thread对象,这个Thread对象才是真正的线程对象
3】通过调用线程对象的start()方法来启动线程

public class MyThread implements Runnable{ // 实现Runnable接口
    public void run(){  // 覆写run()方法
        for(int i=0;i<50;i++){
            System.out.println(Thread.currentThread().getName()
                    + "运行,i = " + i) ;  // 取得当前线程的名字
        }
    }

    public static void main(String args[]){
        MyThread mt = new MyThread() ;  // 实例化Runnable子类对象
        Thread t = new Thread(mt,"线程");     // 实例化Thread对象
        t.start() ; // 启动线程
        for(int i=0;i<50;i++){
            if(i>10){
                try {
                    t.join() ;  // 线程强制运行
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
            System.out.println("Main线程运行 --> " + i) ;
        }
    }

继承Thread类

1】定义Thread类的子类,并重写该类的run()方法,该方法的方法体就是线程需要完成的任务,run()方法也称为线程执行体。
2】创建Thread子类的实例,也就是创建了线程对象
3】启动线程,即调用线程的start()方法

public class Tickets extends Thread {
    public Tickets(String name){
        super(name);
    }
    static int tickets = 20;
    static Object obj = "obj";
    public void run(){

        while (tickets>0){
            synchronized(obj){
                if (tickets>0){
                    System.out.println(getName()+"卖出了"+(21-tickets)+"张票");
                    tickets--;
                }else{
                    System.out.println("票卖完了");
                }
            }
            try {
                sleep(1000);
            }catch(InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

实现Callable接口

而我们在使用Runnable时,会发现它缺少的一项功能,当线程终止时(即run()完成时),我们无法使线程返回结果。为了支持此功能,Java中提供了Callable接口。另外Callable的call ()方法还能抛出异常。

  • 为了实现Runnable,需要实现不返回任何内容的run()方法,而对于Callable,需要实现在完成时返回结果的call()方法。
  • 请注意,不能使用Callable创建线程,只能使用Runnable创建线程。
  • 另一个区别是call()方法可以引发异常,而run()则不能。
  • 为实现Callable而必须重写call方法。
public class MyCallable implements Callable {
    private int id;

    public MyCallable(int id){
        super();
        this.id = id;
    }
    @Override
    public String call() throws Exception {
        System.out.println(">>>" + id + "任务启动");
        Map<String, Object> map = new HashMap<>();
        map.put("id",id);
        String idString = map.get("id").toString()+"aa";
        System.out.println(">>>" + id + "任务进行中");
        System.out.println(">>>" + id + "任务结束");
        return idString;
    }
}

结合Future获取返回值
阿里不允许使用 ExecutorService去创建线程池

public static void main(String[] args) {
        MyCallable myCallable;
        //ExecutorService pool = Executors.newFixedThreadPool(10);
        List<Future> list = new ArrayList<>();
        ThreadPoolExecutor pool = new ThreadPoolExecutor(5,10,60,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(10));
        for (int i = 0;i<10; i++){
            myCallable = new MyCallable(i);
            Future future = pool.submit(myCallable);
            list.add(future);
        }
        for (Future f : list) {
            // 从Future对象上获取任务的返回值,并输出到控制台
            try {
                System.out.println(">>>任务返回值:  " + f.get().toString());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        pool.shutdown();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值