多线程创建

主线程

执行主(main)方法的线程就是主线程。JVM执行main方法,main方法会进入到栈内存,JVM会找操作系统开辟一条main方法通向CPU的执行路径。CPU就可以通过这个路径来执行main方法。而这个路径有一个名字,叫主线程。

Java程序中只有一个线程,执行从main方法开始,从上到下依次执行就是单线程程序。

创建多线程程序的第一种方式:

创建Thread类的子类对象

Java使用java.lang.Thread类代表线程。所有的线程对象都必须是Thread类或者其子类的实例。每个线程的作用是完成一定的任务,实际上就是执行一段程序流即一段顺序执行的代码。Java使用程序执行体来代表这段程序流。

Java中通过继承Thread类来创建并且启动多线程的步骤如下:

  1. 创建一个Thread的子类
  2. 在Thread的子类中重写run方法,设置线程任务。该run()方法的方法体就代表了线程需要完成的任务,因此把run()称之为线程执行体。
  3. 创建Thread的子类对象
  4. 调用Thread类中的方法start方法,开启线程。执行run方法中的方法体

代码举例:

创建新的线程

package demo03;
//继承Thread类,创建子类
public class MyThread extends Thread {
    // 重写run 方法
    @Override
    public void run() {
        // 新的线程要做什么
        for (int i = 0; i < 3; i++) {
            System.out.println("run"+ i);
        }
    }
}

定义测试类

package demo03;

public class MyThreadTest {
    public static void main(String[] args) {
        //创建子线程对象
        MyThread myThread = new MyThread();
        // 启动线程
        myThread.start();
        //主线程里的循环
        for (int i = 0; i < 3; i++) {
            System.out.println("main" + i);
        }
    }
}

执行结果

多线程的原理

 随着Thread子类对象的start方法启动,另外一个新的线程也就启动了。这样整个应用就是多线程了。多线程执行,在栈内存中,其实每一个执行线程都有一片自己所属的栈内存空间。进行方法的压栈和弹栈。多个线程之间毫不影响。

Java.lang.Thread类的构造方法

Thread类常用方法

  • 使用Thread类中的方法 public  String getName() 返回该线程的名称
  • 先获取当前正在执行的线程,使用线程中的方法 public static Thread currentThread() 返回当前正在执行的线程的引用。在使用getName返回线程名称
  • public void start():开启线程。JJVM调用此线程的run方法
  • public void run():此线程要执行的任务,写run里面的代码体
  • public static void sleep(long millis):使当前正在执行的线程以指定的毫秒数暂停。
  • public static Thread currentThread() 返回当前正在执行的线程的引用。

创建多线程程序的第二种方式

实现Runnable 接口

Java.lang.Runnable 接口应该由那些打算通过某一线程执行其实例的类来实现。类必须定义一个称之为run的无参数方法

步骤如下:

  1. 创建一个Runnable 接口的实现类
  2. 在实现类中重写Runnable接口的run方法,设置线程任务
  3. 创建一个Runnable接口的实现类对象
  4. 创建Thread类对象,构造方法中传递Runable接口的实现类对象
  5. 调用Thread类中的start方法,开启新的线程执行run方法

 Thread 和Runnable的区别

如果一个类继承Thread,则不适合资源共享。但是如果实现了Runnable接口的话,很容易实现资源共享。

实现Runnable接口比继续Thread类的优势如下:

  • 适合多个相同的程序代码的线程去共享同一个资源
  • 解决了Java单继承 的局限性
  • 实现了解耦操作,代码和线程之间是独立的
  • 线程池只能放入实现Runnable 或者Callable类的线程,不能直接放入继承Thread的类

结论:

优先使用第二种方式创建多线程

匿名内部类实现线程的操作

匿名内部类可以简化代码

应用场景

匿名内部类必须继承一个父类或者实现一个父接口。实现类只需要使用唯一一次。这种情况下,我们就可以使用匿名内部类。

匿名内部类定义格式:

前提
匿名内部类必须继承一个父类或者实现一个父接口

格式解析:

  • new:创建对象的动作
  • 接口名称:就是匿名内部类需要实现哪个接口
  • {..}这才是的内容

注意事项:

  • 匿名内部类,在创建对象的时候。只能使用唯一一次。
  • 如果希望多次创建,对象或者多次使用对象,则不能使用任何匿名的类或者对象
  • 匿名内部类是省略了(实现类或者子类的名称)。匿名对象是省略的对象名称

代码举例:

package demo01;

public class RunnableTest {
    public static void main(String[] args) {
        //匿名内部类简化代码操作
        new Thread(new Runnable() {
            @Override
            //线程要做的事情
            public void run() {
                for (int i = 0; i < 3; i++) {
                    System.out.println("sun" + i);
                }
            }
            //开启线程
        }).start();

        for (int i = 0; i < 3; i++) {
            System.out.println("main" + i);
        }
    }
}

执行结果

猜你喜欢

转载自www.cnblogs.com/wurengen/p/10809392.html