您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

3种Java创建线程的方式和区别

2025/3/26 20:44:40发布23次查看
在java中如何创建线程?下面本篇文章给大家介绍3种创建线程的方式以及区别。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。
在java中如果要创建线程的话,一般有3种方法:
1、继承thread类;
2、实现runnable接口;
3、使用callable和future创建线程。
【推荐学习:java视频教程】
1. 继承thread类
继承thread类的话,必须重写run方法,在run方法中定义需要执行的任务。
class mythread extends thread{    private static int num = 0;         public mythread(){        num++;    }         @override    public void run() {        system.out.println(主动创建的第+num+个线程);    }}
创建好了自己的线程类之后,就可以创建线程对象了,然后通过start()方法去启动线程。注意,不是调用run()方法启动线程,run方法中只是定义需要执行的任务,如果调用run方法,即相当于在主线程中执行run方法,跟普通的方法调用没有任何区别,此时并不会创建一个新的线程来执行定义的任务。
public class test {    public static void main(string[] args)  {        mythread thread = new mythread();        thread.start();    }}  class mythread extends thread{    private static int num = 0;         public mythread(){        num++;    }         @override    public void run() {        system.out.println(主动创建的第+num+个线程);    }}
在上面代码中,通过调用start()方法,就会创建一个新的线程了。为了分清start()方法调用和run()方法调用的区别,请看下面一个例子:
public class test {    public static void main(string[] args)  {        system.out.println(主线程id:+thread.currentthread().getid());        mythread thread1 = new mythread(thread1);        thread1.start();        mythread thread2 = new mythread(thread2);        thread2.run();    }}  class mythread extends thread{    private string name;         public mythread(string name){        this.name = name;    }         @override    public void run() {        system.out.println(name:+name+ 子线程id:+thread.currentthread().getid());    }}
运行结果:
从输出结果可以得出以下结论:
1)thread1和thread2的线程id不同,thread2和主线程id相同,说明通过run方法调用并不会创建新的线程,而是在主线程中直接运行run方法,跟普通的方法调用没有任何区别;
2)虽然thread1的start方法调用在thread2的run方法前面调用,但是先输出的是thread2的run方法调用的相关信息,说明新线程创建的过程不会阻塞主线程的后续执行。
2. 实现runnable接口
在java中创建线程除了继承thread类之外,还可以通过实现runnable接口来实现类似的功能。实现runnable接口必须重写其run方法。
下面是一个例子:
public class test {    public static void main(string[] args)  {        system.out.println(主线程id:+thread.currentthread().getid());        myrunnable runnable = new myrunnable();        thread thread = new thread(runnable);        thread.start();    }}  class myrunnable implements runnable{         public myrunnable() {             }         @override    public void run() {        system.out.println(子线程id:+thread.currentthread().getid());    }}
runnable的中文意思是“任务”,顾名思义,通过实现runnable接口,我们定义了一个子任务,然后将子任务交由thread去执行。注意,这种方式必须将runnable作为thread类的参数,然后通过thread的start方法来创建一个新线程来执行该子任务。如果调用runnable的run方法的话,是不会创建新线程的,这根普通的方法调用没有任何区别。
事实上,查看thread类的实现源代码会发现thread类是实现了runnable接口的。
在java中,这2种方式都可以用来创建线程去执行子任务,具体选择哪一种方式要看自己的需求。直接继承thread类的话,可能比实现runnable接口看起来更加简洁,但是由于java只允许单继承,所以如果自定义类需要继承其他类,则只能选择实现runnable接口。
3. 使用callable和future创建线程
和runnable接口不一样,callable接口提供了一个call()方法作为线程执行体,call()方法比run()方法功能要强大。
创建并启动有返回值的线程的步骤如下:
创建callable接口的实现类,并实现call()方法,然后创建该实现类的实例(从java8开始可以直接使用lambda表达式创建callable对象)。使用futuretask类来包装callable对象,该futuretask对象封装了callable对象的call()方法的返回值使用futuretask对象作为thread对象的target创建并启动线程(因为futuretask实现了runnable接口)调用futuretask对象的get()方法来获得子线程执行结束后的返回值下面是一个例子:
public class main {public static void main(string[] args){ mythread3 th=new mythread3(); //使用lambda表达式创建callable对象   //使用futuretask类来包装callable对象 futuretask<integer> future=new futuretask<integer>((callable<integer>)()->{return 5;}  ); new thread(task,有返回值的线程).start();//实质上还是以callable对象来创建并启动线程  try{system.out.println(子线程的返回值:+future.get());//get()方法会阻塞,直到子线程执行结束才返回  }catch(exception e){ex.printstacktrace(); }}}
三种创建线程方式对比:
实现runnable和实现callable接口的方式基本相同,不过是后者执行call()方法有返回值,后者线程执行体run()方法无返回值,因此可以把这两种方式归为一种这种方式与继承thread类的方法之间的差别如下:
1、线程只是实现runnable或实现callable接口,还可以继承其他类。
2、这种方式下,多个线程可以共享一个target对象,非常适合多线程处理同一份资源的情形。
3、但是编程稍微复杂,如果需要访问当前线程,必须调用thread.currentthread()方法。
4、继承thread类的线程类不能再继承其他父类(java单继承决定)。
ps:一般推荐采用实现接口的方式来创建多线程
本文来自 java入门 栏目,欢迎学习!
以上就是3种java创建线程的方式和区别的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product