当前位置: 首页 > article >正文

多线程(2)线程创建的两种方法

多线程(2) 线程创建1、2

线程创建1  继承Thread类

具体步骤:

(1)创建一个继承于Thread类的子类

(2)重写Thread类的run()方法---->将此线程要执行的操作声明在此方法体中。

(3)创建当前Thread子类的对象

(4)通过对象调用start()方法;

典例如下:

public class EvenNumber {
    public static void main(String[] args) {
        Print p = new Print();
        p.start();//调用父类中的方法。(1)启动线程(2)调用当前线程的run()方法
        for (int i = 0; i <=100; i++) {
            if(i%2==0)
                System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}
class Print extends Thread{
    @Override
    public void run() {
        for (int i = 0; i <=100; i++) {
            if(i%2==0)
                System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}

注意事项:

1) start()方法通过一系列的内部机制,包括线程状态的转换、线程调度、回调机制以及本地方法的调用,最终导致run()方法被自动执行

而直接调用run()方法则不会启动新线程,而是在当前线程中顺序执行,因此无法实现多线程的效果。

2)不能在一个已经调用过start()方法的线程二次执行start()方法,否则报异常IllegalThreadStateException

public class OddNumber {
    public static void main(String[] args) {
/*        Odd o1 = new Odd();
        Even e1 = new Even();
        o1.start();
        e1.start();*/   //标准写法

/*        new Odd().start();
        new Even().start();*///匿名对象

        new Thread(){
            @Override
            public void run() {
                for (int i = 0; i <100 ; i++) {
                    if(i%2!=0)
                        System.out.println(i);
                }
            }
        }.start();

        new Thread(){
            @Override
            public void run() {
                for (int i = 0; i <100 ; i++) {
                    if(i%2==0)
                        System.out.println(i);
                }
            }
        }.start();//匿名子类匿名对象

    }
}

class Odd extends Thread{
    @Override
    public void run() {
        for (int i = 0; i <100 ; i++) {
            if(i%2!=0)
                System.out.println(i);
        }
    }
}
class Even extends Thread{
    @Override
    public void run() {
        for (int i = 0; i <100 ; i++) {
            if(i%2==0)
                System.out.println(i);
        }
    }
}

线程创建2  实现Runnable接口

java有单继承的限制,当我们无法继承Thread类时,那么该如何做呢?在核心类库中提供了Runnable接口,我们可以实现Runnable接口,重写run()方法,然后再通过Thread类的对象代理启动和执行我们的线程体run()方法

具体步骤:

(1)创建一个实现Runnable 接口的类

(2)实现接口中的run()方法

(3)创建实现类的对象

(4)将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例

(5)Thread的实例调用start()方法

典例如下;

public class EvenNumber {
    public static void main(String[] args) {
        Even e1 = new Even();//创建实现类对象
        Thread t1 = new Thread(e1);//创建Thread类的对象,并且把实现类的对象作为实参传给形参。调用父类中的构造器。
        Thread t2 = new Thread(e1);
        t1.start();//用Thread实例调用start方法
        t2.start();
    }
}

class Even implements Runnable{
    @Override//实现Runnable类,重写run方法
    public void run() {
        for (int i = 0; i < 100; i++) {
            if(i%2==0)
                System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}

通过实现Runnable接口,使得该类有了多线程类的特征。所有的分线程要执行的代码都在run方法里面。

在启动多线程的时候,需要先通过Thread类的构造方法Thread(Runnable target) 构造出对象,然后调用Thread对象的start()方法来运行多线程代码。

说明:Runnable对象仅仅作为Thread对象的target,Runnable实现类里包含的run()方法仅作为线程执行体。 而实际的线程对象依然是Thread实例,只是该Thread线程负责执行其target的run()方法。

对比两种方式

联系

Thread类实际上也是实现了Runnable接口的类。即:

public class Thread extends Object implements Runnable

区别

  • 继承Thread:线程代码存放Thread子类run方法中
  • 实现Runnable:线程代码存在接口的子类的run方法

实现Runnable接口比继承Thread类所具有的优势

  • 避免了单继承的局限性
  • 多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处理同一份资源。
  • 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。

结论;一般建议使用 实现Runnbale接口的方案创建多线程。


http://www.kler.cn/a/413807.html

相关文章:

  • SNMPv3 项目实例
  • python的字体如何调整
  • Unity类银河战士恶魔城学习总结(P149 Screen Fade淡入淡出菜单)
  • 【安全 - openssl 生成密钥对和CSR】
  • FCBP 认证考试要点摘要
  • sin函数拟合
  • 设计模式之 备忘录模式
  • 使用Kamailio实现VoIP通话流程详解
  • 【Java 学习】面向程序的三大特性:封装、继承、多态
  • XSS--跨站脚本攻击
  • “python+ADCIRC”潮汐、风驱动循环、风暴潮等海洋水动力模拟
  • Vue 3 路由教程
  • 计算机网络八股整理(三)
  • 计算分数的浮点数值
  • 112. UE5 GAS RPG 制作高亮接口
  • WPF的表格控件 FlexGrid设置行的高度自适应
  • 【优选算法】位运算
  • 面经-综合面/hr面
  • shell脚本_不同脚本的互相调用和重定向操作
  • 【Linux】命令行参数与环境变量