Java多线程2:多线程程序的2种实现方式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yuming226/article/details/82839978
前言

一个进程正在运行时至少会有1个线程在运行,这种情况载Java中也是存在的。这些线程在后台默默的执行,比如 public static void main(String[] args)方法的线程就是这样的,而且它是由JVM创建的。
代码如下:

public class Test {
	public static void main(String[] args) {
		System.out.println(Thread.currentThread().getName());
	}
}

程序运行后的效果如下:
在这里插入图片描述

多线程实现方式1

1 继承Thread
(1)定义类继承Thread。
(2)重写run方法。
(3)把新线程要做的事写在run方法中。
(4)创建线程对象。
(5)开启新线程,内部会自动执行run方法。

线程实现代码如下:

public class Demo2_Thread {
     /**
      * 演示多线的创建
      */
     public static void main(String[] args) {
          MyThread mt = new MyThread(); //4,创建线程的子类对象
          //mt.run();
          mt.start();                           //5,开启线程
          
          for(int i = 0; i < 10000; i ++) {
              System.out.println(i + " bb");
          }
          
     }    
}
class MyThread extends Thread {   //1,继承Thread
     public void run() {          //2,重写run方法
          for(int i = 0; i < 10000; i ++){//3,将要执行的代码写在run方法中
              System.out.println(i + " aaaaaaaaaaaaaaaa");
          }
     }
}

效果如下:
在这里插入图片描述
注意:在使用多线程技术时,代码的运行结果与代码执行顺序或调用顺序是无关的。

多线程程序实现方式2

1 实现Runnable
(1)定义类实现Runnable接口。
(2)实现run方法。
(3)把新线程要做的事写在run方法中。
(4)创建自定义的Runnable的子类对象。
(5)创建Thread对象,传入Runnable。
(6)调用start()开启新线程,内部会自动调用Runnable的run()方法。

线程实现代码如下:

public class Demo3_Thread {
     
     public static void main(String[] args) {
          MyRunnable mr = new MyRunnable(); //4,创建Runnable的子类对象
          //Runnable target = mr;
          Thread t = new Thread(mr);            //5,将其当作参数传递给Thread的构造函数
          t.start();                                 //6,开启线程
     }
}
class MyRunnable implements Runnable{
     @Override
     public void run() {          //2,重写run方法
          for(int i = 0; i < 1000; i ++) {  //3,将要执行的代码写在run方法中
              System.out.println("aaaaaaaaaaa");
          }
     }
}

实现Runnable的原理

1 查看源码:
(1)看Thread类的构造函数,传递了Runnable接口的引用。
(2)通过init()方法找到传递的target给成员变量的target赋值。
(3)查看run方法,发现run方法中有判断,如果target不为null就会调用Runnable接口子类对象的run方法。

两种方式的区别

1 查看源码的区别:
(1)继承Thread:由于子类重写了Thread类的run(),当调用start()时,直接找子类的run()方法。
(2)实现Runnable:构造函数中传入了Runnable的引用,成员变量记住了它,start()调用run()方法时内部判断成员变量Runnable的引用是否为空,不为空编译时看的是Runnable的run(),运行时执行的是子类的run()方法。

继承Thread

好处:可以直接使用Thread类中的方法,代码简单。
弊端:如果已经有了父类,就不能用这种方法。

实现Runnable接口

好处:即使自己定义的线程类有了父类也没关系,因为有了父类也可以实现接口,而且接口是可以多实现的。
弊端:不能直接使用Thread中的方法,需要先获取到线程对象后,才能得到Thread的方法,代码复杂。

匿名内部类实现线程的两种方式
public class Demo4_Thread {
     
     public static void main(String[] args) {
          new Thread() {                             //1,继承Thread类
              public void run() {                    //2,重写run方法
                   for(int i = 0; i < 10000; i ++) {//3,将要执行的代码写在run方法中
                        System.out.println("aaaaaaaaaaaaaaaaa");
                   }
              }
          }.start();
          
          new Thread(new Runnable() {
              public void run() {
                   for(int i = 0 ; i < 10000; i ++) {
                        System.out.println("bb");
                   }
              }
          }).start();
     }
}

获取线程的名字和设置线程的名字
public class Dmeo5_ThreadName {
     public static void main(String[] args) {
          /*new Thread() {
              public void run() {
                   this.setName("张三");
                   System.out.println(this.getName() + ".....aaaaaaaaaaaaa");
              }
          }.start();
          
          new Thread() {
              public void run() {
                   this.setName("李四");
                   System.out.println(this.getName() + "...bb");
              }
          }.start();*/
          
     Thread th1 = new Thread() {
              public void run() {
                   System.out.println(this.getName() + ".....aaaaaaaaaaaaa");
              }
          };
          
          Thread th2 = new Thread() {
              public void run() {
                   System.out.println(this.getName() + "...bb");
              }
          };
          th1.setName("张三");
          th2.setName("李四");
          th1.start();
          th2.start();
          
     }
     
     public static void demo() {
          //通过构造方法给那么赋值
                   new Thread("张三") {
                        public void run() {
                             System.out.println(this.getName() + " aaaaaaaaaaaaa");
                        }
                   }.start();
                   
                   new Thread("李四") {
                        public void run() {
                             System.out.println(this.getName() + " bb");
                        }
                   }.start();
                   
          
     }
}

猜你喜欢

转载自blog.csdn.net/yuming226/article/details/82839978