创建线程类

多线程的原理

程序启动运行main时候,java虚拟机启动一个进程,主线程main在main()调用时候被创建。随着Thread的子对象的调用start方法,另外一个新的线程也启动了,这样,整个应用就在多线程下运行。多线程的执行流程,那么为什么可以完成并发执行呢? 多线程执行时,在栈内存中,其实每一个执行线程都有一片自己所属的栈内存空间。进行方法的压栈和弹栈。多个线程之间互不影响(在不同的栈空间)

主线程

执行主方法(main)的线程就是主线程。单线程程序:Java程序中只有一个线程,执行从main方法开始,从上到下依次执行。main方法通向CPU的路径,这个路径叫主线程。

创建多线程的第一种方式:继承Thread类

Java使用 java.lang.Thread 类代表线程,所有的线程对象都必须是Thread类或其子类的实例。每个线程的作用是 完成一定的任务,实际上就是执行一段程序流即一段顺序执行的代码。Java使用线程执行体来代表这段程序流。
创建并启动多线程的步骤如下
  • 创建一个类,继承Thread类
  • 重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务,因此把 run()方法称为线程执行体。
  • 创建Thread子类的实例,即创建了线程对象
  • 调用线程对象的start()方法来启动该线

 注意事项:

  • 线程对象调用start方法,多个线程会并发执行
  • 多次启动一个线程是非法的,特别是当线程已经结束执行后,不能在重新启动

Thread类

构造方法:

  • public Thread() :分配一个新的线程对象。
  • public Thread(String name) :分配一个指定名字的新的线程对象。
  • public Thread(Runnable target) :分配一个带有指定目标新的线程对象。
  • public Thread(Runnable target,String name) :分配一个带有指定目标新的线程对象并指定名字。

常用方法:

  • public String getName() :获取当前线程名称。
  • public void start() :导致此线程开始执行; Java虚拟机调用此线程的run方法。
  • public void run() :此线程要执行的任务在此处定义代码。
  • public static void sleep(long millis) :使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)。
  • public static Thread currentThread() :返回对当前正在执行的线程对象的引用。

代码举例

package demo01;

public class Demo01Thread extends Thread {//创建一个类,继承Thread类


    @Override
    //重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务,因此把 run()方法称为线程执行体。
    public void run() {
        //线程执行体。线程任务
        for (int i = 0; i < 5; i++) {
            System.out.println("run" + i);
        }
    }
}
package demo01;

public class Demo01ThreadTest {
    public static void main(String[] args) {
        //创建Thread子类的实例,即创建了线程对象
        Demo01Thread demo01Thread = new Demo01Thread();
        //调用线程对象的start()方法来启动该线
        demo01Thread.start();
        //设置主线程任务
        for (int i = 0; i < 5; i++) {
            System.out.println("main"+i);
        }

    }
}

执行结果

run0
main0
run1
main1
run2
main2
run3
main3
run4
main4 

创建多线程的第二种方式:实现Runnable接口

采用 java.lang.Runnable 也是非常常见的一种,我们只需要重写run方法即可。
步骤如下:
  1. 定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。
  2. 创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
  3. 调用线程对象的start()方法来启动线程。

代码举例

package demo03;

//定义Runnable接口的实现类
public class Demo01Runnable implements Runnable {

    @Override
    //重写该接口的run()方法
    public void run() {
        //获取线程名称
        System.out.println(Thread.currentThread().getName());
        //该run()方法的方法体同样是该线程的线程执行体。
        for (int i = 0; i < 3; i++) {
            System.out.println("run" + i);
        }
    }
}
package demo03;

public class Demo01RunnableTest {
    public static void main(String[] args) {
        //创建Runnable实现类的实例
        Demo01Runnable d = new Demo01Runnable();
        //并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
        Thread thread = new Thread(d);
        //调用线程对象的start()方法来启动线程。
        thread.start();
        //获取线程名称
        System.out.println(Thread.currentThread().getName());

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

    }
}

执行结果

main
Thread-0
main0
main1
main2
run0
run1
run2

Thread和Runnable的区别

如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。
总结:
  • 实现Runnable接口比继承Thread类所具有的优势:
  • 适合多个相同的程序代码的线程去共享同一个资源。
  • 可以避免java中的单继承的局限性。
  • 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。
  • 线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类。

匿名内部类方式实现线程的创建

package demo03;

public class Demo02RunnableTest {
    public static void main(String[] args) {
        /*使用线程的内匿名内部类方式,可以方便的实现每个线程执行不同的线程任务操作。
          使用匿名内部类的方式实现Runnable接口,重新Runnable接口中的run方法:
        * */
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 3; i++) {
                    System.out.println("run" + i);
                }
            }
        }).start();
        for (int i = 0; i < 3; i++) {
            System.out.println("main" + i);
        }
    }
}
 

猜你喜欢

转载自www.cnblogs.com/wurengen/p/10926685.html
今日推荐