java多线程的创建

方法一:继承Thread类

        java是通过java.lang.Thread类来代表线程

        1.定义一个MyThread继承线程类java.lang.Thread,重新run()方法        

        2.创建MyThread对象。

        4.调用线程对象start()方法启动线程(启动后还是执行run方法)

package com.Thread.create;

public class MyThreadDemo1 {
    public static void main(String[] args) {
        //new一个对象调用start方法开始执行线程
        new Mythread().start();


        for (int i = 0; i < 500; i++) {
            System.out.println("主要的线程");
        }
    }
}



//1.定义一个线程类继承Thread
class Mythread extends Thread{
//2.重写run方法
    @Override
    public void run() {
        for (int i = 0; i <500; i++) {
            System.out.println("线程输出"+i);
        }
    }
}

优缺点:

优点:编码简单

缺点:线程类已继承Thread,无法继承其他类,不利于扩展

使用注意:        

        为什么不直接调用run方法,而是调用start启动线程。

                直接调用run方法会当成普通方法执行,此时相当于还是单线程。

                只有调用start方法才是启动一个新线程。

        主线程任务不要放到子线程之前:

                因为这样也会当做单线程来执行的。

方法二:实现Runable接口

       1.定义一个线程任务MyRunable实现Runable接口,重写run()方法

        2.创建MyRunable任务对象

        3.把MyRunable任务对象交给Thread处理

        4.调用线程对象的start()方法启动线程

package com.Runable.create;




/*
       目标:线程的创建方式二,理解它的优缺点
 */
public class ThreadDemo2 {
    public static void main(String[] args) {
        //3创建任务对象
        Runnable target = new MyRunnable();
        //4 把线程对象交给Thread去处理,并且启动start
        new Thread(target).start();
        for (int i = 0; i < 500; i++) {
            System.out.println("我是======================================");
        }

    }
}
/*
    1定义一个线程任务类 实现runable接口
 */
class MyRunnable implements Runnable{

    /*
        2重写run方法,定义线程任务
     */

    @Override
    public void run() {
        for (int i = 0; i < 500; i++) {
            System.out.println("子线程任务"+i);
        }
    }
}

优缺点:

        优点:线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。

        缺点:编程多一层对象包装,如果线程有执行结果是不可以直接返回的。

实现Runable接口(匿名内部类)

        1.创建Runable匿名内部类对象

        2.交给Thread处理。

        3.调用线程对象的start()启动线程。

package com.Runable.create;




/*
       目标:线程的创建方式二,理解它的优缺点
 */
public class ThreadDemo3 {
    public static void main(String[] args) {

        //匿名内部类的形式
        Runnable target = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 50; i++) {
                    System.out.println("我是子线程1*");
                }

            }
        };
        new Thread(target).start();

        //主线程
        for (int i = 0; i < 50; i++) {
            System.out.println("我是主线程");
        }

        //匿名内部类的第二种形式。
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 50; i++) {
                    System.out.println("我是子线程2*");
                }
            }
        }).start();


    }
}
/*

 */

方法三:实现Callable接口

利用callable、FutureTask接口实现

1.得到任务对象

        1.定义类实现Callable接口,重写call方法,封装要做的事情。

        2.用FutureTask把Callable对象封装成线程任务对象。

2.把线程任务交给Thread处理

3.调用Thread的start方法启动线程,执行任务。

4.线程执行完毕后,通过FutureTask的get方法去获取执行结果

package com.Runable.create;


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

/*
    实现callable接口,给FutureTask完成
 */
public class ThreadDemo4 {
    public static void main(String[] args) {
        /*
            3.创建任务对象

         */
        Callable<String> call  = new MyCallable(100);
        /*
            4.把callable任务对象交给Futuretast对象
            FutureTask对象的作用1:是Runable的对象(实现了Runnable接口),可以交给Thread
            FutureTask对象的作用2:可以在线程执行完毕之后通过其get方法得到线程的执行结果

         */

        FutureTask<String> f1 = new FutureTask<String>(call);

        /*
            5、交给线程处理
         */

        new Thread(f1).start();




        Callable<String> call1  = new MyCallable(100);
        FutureTask<String> f2 = new FutureTask<String>(call1);
        new Thread(f2).start();


        try {
            String rs1= f1.get();
            System.out.println("第一个结果:"+rs1);
        } catch (Exception e) {

        }


        try {
            String rs2= f2.get();
            System.out.println("第二个结果:"+rs2);
        } catch (Exception e) {

        }

    }
}


/*
    1.定义任务类。实现Callable接口 应该声明线程任务执行完毕后的结果数据类型
 */

class MyCallable implements Callable<String>{
    private int n;

    public MyCallable(int n) {
        this.n = n;
    }
    /*
        2.重写call方法(线程的任务方法)
     */

    @Override
    public String call() throws Exception {
        int sum = 0;
        for (int i = 0; i <=n; i++) {
            sum+=i;

        }
        return "子线程执行的结果是:"+sum;
    }
}

       优缺点: 

优点:线程任务只是实现接口,可以继续继承类和实现接口,扩展性强。

              可以在线程执行完毕后去获取线程的执行结果

缺点:

        编码复杂一点。

三种方法的对比:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值