主线程

  主线程即main线程,main方法是程序的入口,执行main方法时,JVM会找到操作系统开辟一条main方法通向CPU的执行路径,CPU就可以通过该路径来执行main方法。同样的道理,当我们在main方法中开启了新的线程时,JVM也会开辟新的路径通向CPU,让CPU可以通过新的路径执行新的线程任务。且在JVM中,线程的调度是抢占式调度,即哪一个线程的优先度高,就执行哪个线程。

 

 了解Thread:

 

创建多线程的方式_多线程

Thread中常用的方法:


  public void start() :导致此线程开始执行; Java虚拟机调用此线程的run方法。


  public String getName() :获取当前线程名称。


  public void setName() :设置此线程的名称,等同于在子类中使用带参的构造方法 Thread(String name)。


  public void run() :此线程要执行的任务在此处定义代码。


  public static void sleep(long millis) :使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)。


  public static Thread currentThread() :返回对当前正在执行的线程对象的引用。


 


对于上面的两个静态方法,直接使用Thread.方法()进行调用


第一种方式:创建一个类并继承类Thread:

java.lang.Thread类:是描述线程的类,要想实现多线程,就必须继承Thread类

实现步骤:

  1.创建一个Thread类的子类

  2.在该子类中重写run方法,设置线程任务(即设置该线程做什么)

  3.创建该子类对象

  4.子类对象调用Thread类中的start方法,开启新的线程,此时就会自动执行子类中的run方法

 注意:若此时子类对象直接调用run方法,那么是不会开启新的线程的。

 

第二种方式:创建一个类并实现接口Runnable:

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

实现步骤:

  1.创建一个Runable接口的实现类

  2.在该实现类中重写Runable接口的run()方法,设置线程任务(即设置该线程做什么)

  3.创建一个实现类对象

  4.新建一个Thread对象,在构造方法中传递实现类对象作为参数

  5.Thread对象调用start()方法,开启新线程执行run()方法

注意:实现了Runable接口后,依然需要Thread类去调用start()方法,才能开启新线程。即Runnable实现类只负责设置线程任务,

而开启新线程的任务就交给了Thread类去完成,也就是实现了解耦。

知识点:

  1.public class Thread extends Objectimplements Runnable :Thread类其实也是实现了Runable接口


  2.通过实现Runnable接口,使得该类有了多线程类的特征。run()方法是多线程程序的一个执行目标。所有的多线程


代码都在run方法里面。Thread类实际上也是实现了Runnable接口的类。


  3.在启动的多线程的时候,需要先通过Thread类的构造方法Thread(Runnable target) 构造出对象,然后调用Thread


对象的start()方法来运行多线程代码。


  4.实际上所有的多线程代码都是通过运行Thread的start()方法来运行的。因此,不管是继承Thread类还是实现


Runnable接口来实现多线程,最终还是通过Thread的对象的API来控制线程的,熟悉Thread类的API是进行多线程


编程的基础。


 


使用Runable开启新线程的好处:


  1.避免单继承的局限性:如果一个类继承了Thread类,就不能再继承其他类了。因为在java中,一个类只能有一个父类,而实现的接口却可以有很多个。


  2.增强程序的拓展性:实现了Runable接口后,就把设置线程任务和开启新线程进行了分离,即实现了程序的解耦


 


 


 


第二种方式示例:




//    1.新建一个实现类,实现Runnable接口
public class MyRunnable implements Runnable {
// 2.重写run()方法
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("你爱我,我爱你,蜜雪冰城甜蜜蜜"+i);
}
}
}



public class TestMyRunnable {

public static void main(String[] args) throws InterruptedException {
// 3.新建实现类对象
MyRunnable mr = new MyRunnable();
// 4.新建Thread对象,并把实现类对象传递给其构造方法做参数
Thread thread = new Thread(mr);
// 5.thread调用start方法,开启新的线程
thread.start();
// 调用getName()方法
String name1 = thread.getName();
System.out.println(name1);//Thread-0

// 开启main线程
for (int i = 0; i < 10; i++) {
System.out.println("鸿星尔克好样的!"+i);
}

//调用currentThread()方法
String name2 = Thread.currentThread().getName();//main
//调用sleep()方法,睡眠2秒钟
Thread.sleep(2000);
System.out.println(name2);

}
}


我们发现上面的实现类其实可以用匿名内部类来实现。

使用匿名内部类



public class NoNameInnerClass {
public static void main(String[] args) {

// 1.使用匿名内部类,新建Runnable对象,并重写run()方法
Runnable mr = new Runnable() { //多态,子类对象指向父类。因为此时new Runnable(){}就相当于一个Runnable的实现类
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("河南加油!!!"+i);
}
}
};
// 2.新建Thread对象,并把Runnable对象传递给Thread对象
Thread mt = new Thread(mr);
// thread调用start()方法,开启新线程
mt.start();
}
}