JAVA多线程的四种实现方式

JAVA多线程的四种实现方式:

  1. 继承Thread类
  2. 实现Rannable接口
  3. 实现Callable接口通过FutureTask包装器来创建Thread线程
  4. 通过线程池创建线程,使用线程池接口ExecutorService结合Callable和FutureTask来实现有返回结果的多线程。

前两种【无返回值】原因:通过重写run方法,run方法的返回值是void,所以没有办法返回结果。
后两种【有返回值】原因:通过实现Callable接口,要重写call方法,call方法的返回值类型是object,所以可以将返回的值存在Object对象中

方式一:继承Thread类:

实现步骤:
1.创建一个Thread子类
2.在Thread中重写run(方法),设置线程任务
3.创建线程子类对象
4.调用线程的start方法,开启新的线程,执行run方法里的代码

public class MyThread extends Thread{		//1.继承Thread类
    @Override		//2.重写run方法,设置线程任务
    public void run() {
        System.out.println("创建的线程执行了");
    }
}
public class ThreadDemo1 {
    public static void main(String[] args) {
        MyThread myThread1 = new MyThread();		//3.创建线程子类对象
        MyThread myThread2 = new MyThread();
        myThread1.start();		//调用线程中的start方法,开启新的线程,并执行run方法里的代码
        myThread2.start();
        System.out.println("主方法中的线程执行了");
    }
}

方式二:实现Runnable接口创建线程

如果自己的类已经extends另一个类,就无法直接extends Thread,此时,可以实现一个Runnable接口。
实现步骤:
1.创建一个Runnable实现类
2.实现类中重写run方法,设置线程任务
3.创建一个实现类对象
4.创建一个Thread类对象,并通过构造方法传入一个Runnable实现类对象
5.调用Thread类中的start方法,开启新线程的run方法

public class MyThread implements Runnable{		//1.创建一个Runnable实现类
    @Override		//2.实现类中重写run方法,设置线程任务
    public void run() {
        System.out.println("创建的线程被执行了");
    }
}
public class ThreadDemo1 {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();		//创建一个实现类对象
        Thread thread = new Thread(myThread);		//创建Thread类对象,并通过构造方法传入Runable实现类对象
        thread.start();		//调用Thread类中的start方法开启新线程的run方法
        System.out.println("主方法中的线程执行了");
    }
}

当传入一个Runnable target参数给Thread后,Thread的run()方法就会调用target.run(),参考Thread源码:

@Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

实现runnable接口创建线程的好处?
1.避免了java中单继承的局限性,继承了Thread类就无法继承其他类,实现Runnable接口还可以继承其他类,实现其他接口。
2.增强了程序的健壮性,降低了程序的耦合性(解耦)。把设置线程任务和开启线程任务分开,在实现类中重写run方法设置线程任务,在Thread类中调用start方法中开启线程任务,代码可以被多个线程共享,代码和数据之间相互独立
3.线程池中只能存放实现Runnable接口和Callable接口的线程,不能存放继承Thread类的线程

方式三:通过Callable和FutureTask创建线程

实现步骤:

  1. 创建Callable接口的实现类 ,并实现Call方法
  2. 创建Callable实现类的实现,使用FutureTask类包装Callable对象,该FutureTask对象封装了Callable对象的Call方法的返回值
  3. 使用FutureTask对象作为Thread对象的target创建并启动线程
  4. 调用FutureTask对象的get()来获取子线程执行结束的返回值
public class SomeCallable implements Callable { //创建Callable接口的实现类

    @Override
    public Object call() throws Exception {		//实现call方法
        System.out.println("我是通过实现Callable接口通过FutureTask包装器来实现的线程");
        return null;
    }
}
public class ThreadDemo1 {
    public static void main(String[] args) {
        System.out.println("我是主方法的线程");
        Callable someCallable = new SomeCallable();
        由Callable<Integer>创建一个FutureTask<Integer>对象:  
        FutureTask futureTask = new FutureTask<Object>(someCallable);
        注释:FutureTask<Integer>是一个包装器,它通过接受Callable<Integer>来创建,它同时实现了Future和Runnable接口。 
        Thread thread = new Thread(futureTask);
        //由FutureTask<Integer>创建一个Thread对象:   
        thread.start();
    }
}

方式四:通过线程池创建线程

实现步骤:
1.创建线程池工厂类Executors,里面提供静态方法newFixedThreadPool生产一个指定数量的线程池
2.创建一个类,实现Runnable接口重写run方法,设置线程任务
3.调用ExecutorService中的submit方法,传递线程任务,开启线程执行任务
4.调用ExecutorService中的shutdown方法,销毁线程池(不推荐的,一般线程池里的线程用完之后归还即可,没有必要销毁线程池)

public class ThreadPool {
    public static void main(String[] args) {
        //1.创建线程池工厂类Executors,里面提供静态方法newFixedThreadPool生产一个指定数量的线程池
        ExecutorService es = Executors.newFixedThreadPool(3);
        Runnable r = new RunnableImpl();
        //3.调用ExecutorService中的submit方法,传递线程任务,开启线程执行任务
        es.submit(r);  //pool-1-thread-2正在运行
        es.submit(r);  //pool-1-thread-1正在运行
        es.submit(r);  //pool-1-thread-2正在运行
        //4.调用ExecutorService中的shutdown方法,销毁线程池(不推荐的,一般线程池里的线程用完之后归还即可,没有必要销毁线程池)
        es.shutdown();
    }
}
//2.创建一个类,实现Runnable接口重写run方法,设置线程任务
public class RunnableImpl implements Runnable {
    private int tickets =100;
    Object obj =new Object();
    @Override
    public void run() {
        // System.out.println(this);
        while (true){
            synchronized (obj){
                if (tickets>0){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"正在卖第"+tickets+"张票");
                    tickets--;
                }else {
                    break;
                }
            }
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值