• Java基础——多线程(二)——创建线程的两种方式及区别


    创建线程有两种方法:

    • 需要从Java.lang.Thread类派生一个新的线程类,重写它的run()方法; 
    • 实现Runnalbe接口,重载Runnalbe接口中的run()方法。

    一、将类声明为Thread的子类。该子类应重写Thread 类的 run 方法(线程之间相互独立,不可共享资源)。接下来可以分配并启动该子类的实例。

    例如,计算大于某一规定值的质数的线程可以写成:

     

         class PrimeThread extends Thread {
             long minPrime;
             PrimeThread(long minPrime) {
                 this.minPrime = minPrime;
             }
     
             public void run() {
                 // compute primes larger than minPrime
                  . . .
             }
         }

    然后,下列代码会创建并启动一个线程:

         PrimeThread p = new PrimeThread(143);
         p.start();

    代码示例:

    class Demo_01 extends Thread{
        private String name;
        Demo_01(String name){
            super(name);
            //this.name = name;
        }
    
        public void run(){
            for(int x = 0; x < 10; x++){
                for (int y = 0; y < 7777777; y++){}
                System.out.println("..."+"x="+x+"..."+Thread.currentThread().getName());
            }
        }
    }
    
    public class Test_01 {
    
        public static void main(String[] args) {
    
            Demo_01 d1 = new Demo_01("张三");
            Demo_01 d2 = new Demo_01("lisi");
            d1.start();
            d2.start();
        }
    }

    二、声明实现 Runnable 接口的类(实现Runable接口)。该类然后实现 run 方法。然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。(可以线程之间相互独立,不可共享资源。也可以所有线程共享同一资源)

    采用这种风格的同一个例子如下所示:

     

         class PrimeRun implements Runnable {
             long minPrime;
             PrimeRun(long minPrime) {
                 this.minPrime = minPrime;
             }
     
             public void run() {
                 // compute primes larger than minPrime
                  . . .
             }
         }

    然后,下列代码会创建并启动一个线程:

         PrimeRun p = new PrimeRun(143);
         new Thread(p).start();

    代码示例:

    //一、线程独立拥有资源,互不影响
    class Demo_02 implements Runnable{
    
        public void run(){
            show();
        }
    
        private void show() {
            for (int i = 0; i < 20; i++){
                System.out.println(Thread.currentThread().getName()+"..."+i);
            }
        }
    }
    
    public class Test_02 {
        public static void main(String[] args) {
            Demo_02 d1 = new Demo_02();
            Demo_02 d2 = new Demo_02();
    
            Thread t1 = new Thread(d1);
            Thread t2 = new Thread(d2);
            t1.start();
            t2.start();
        }
    }
    
    //二、线程共享资源
    class Demo_02 implements Runnable{
    
        private int i = 20;
        public void run(){
            show();
        }
        private void show() {
            while(i > 0){
                System.out.println(Thread.currentThread().getName()+"..."+i);
            }
        }
    }
    
    public class Test_02 {
        public static void main(String[] args) {
            Demo_02 d = new Demo_02();
    
            Thread t1 = new Thread(d);
            Thread t2 = new Thread(d);
            t1.start();
            t2.start();
        }
    }

    每个线程都有一个标识名,多个线程可以同名。如果线程创建时没有指定标识名,就会为其生成一个新名称。

    上述内容详见Java JDK API 文档

    两种创建方式的区别

    在Java中,类仅支持单继承,也就是说,当定义一个新的类的时候,它只能扩展一个外部类.这样,如果创建自定义线程类的时候是通过扩展 Thread类的方法来实现的,那么这个自定义类就不能再去扩展其他的类,也就无法实现更加复杂的功能。因此,如果自定义类必须扩展其他的类,那么就可以使用实现Runnable接口的方法来定义该类为线程类,这样就可以避免Java单继承所带来的局限性。

      还有一点最重要的就是使用实现Runnable接口的方式创建的线程可以处理同一资源,从而实现资源的共享.

    通过扩展Thread类来创建多线程,虽然执行的是相同的代码,但彼此相互独立,且各自拥有自己的资源,互不干扰。

    通过实现Runnable接口来创建多线程,程序在内存中仅创建了一个资源,而新建的三个线程都是基于访问这同一资源的,并且由于每个线程上所运行的是相同的代码,因此它们执行的功能也是相同的。

    详见:Java中实现多线程两种方式之间的区别

  • 相关阅读:
    转 进程与线程的区别与联系
    DoEvents的应用及注意事项
    转:error LNK2001 错误
    基于UDP的简单的聊天程序
    VB提示:文件未找到:'c:\windows\sytem32\ieframe.dll\1'的解决方法
    VB PopupMenu方法
    转 vb中SetWindowsHookEx详细用法及举例
    Python批量转换txt文件为excel文件
    excel自动筛选后分别复制粘贴到新文件的解决办法
    文本编辑
  • 原文地址:https://www.cnblogs.com/itjiangpo/p/14181245.html
Copyright © 2020-2023  润新知