我们运行程序,是通过进程中的线程来运行的。一个进程可以包括一个或多个线程,那么如何让一个程序能多线程运行呢?

这里有两种方法

一个是新线程类继承Thread,在run()方法中写方法体,然后调用start()方法执行
第二种是新线程类implements实现Runnable接口,然后该类实现run方法。然后可以分配该类的实例,创建一个Thread对象,在创建Thread对象时作为一个参数传递给Thread对象,然后用Thread对象调用start()方法

先说第一种方法

首先创建一个类class

package Thread_Learn;

public class Thread_01 extends Thread {
	//在run方法中写需要线程执行的程序
	public void run(){
		for(int i=0;i<50;i++) {
			//继承了Thread类 所以可以直接调用getName()方法获取当前线程的线程名
			System.out.println(getName()+i);
		}
		
	}
}

这个类继承了Thread,那么它就是一个可以独立运行的线程了,现在我们来调用一下它

package Thread_Learn;

public class Main {
public static void main(String[] args) {
	//创建一个新线程的类的对象
	Thread_01 th_01 = new Thread_01();
	//给线程设置个名字
	th_01.setName("线程1-");
	//开始执行线程
	th_01.start();
	for(int i=0;i<50;i++) {
		System.out.println("主线程-"+i);
	}
}
}

可以看到运行结果
线程1-0
主线程-0
主线程-1
主线程-2
主线程-3
线程1-1
主线程-4
线程1-2
主线程-5
线程1-3
主线程-6
线程1-4
主线程-7
线程1-5
主线程-8
线程1-6
主线程-9
线程1-7
主线程-10
线程1-8
主线程-11
主线程-12
主线程-13
主线程-14
主线程-15
主线程-16
主线程-17
主线程-18
主线程-19
主线程-20
主线程-21
主线程-22
主线程-23
主线程-24
线程1-9
主线程-25
线程1-10
线程1-11
线程1-12
主线程-26
线程1-13
主线程-27
线程1-14
线程1-15
线程1-16
线程1-17
主线程-28
线程1-18
主线程-29
线程1-19
主线程-30
线程1-20
主线程-31
线程1-21
主线程-32
线程1-22
主线程-33
线程1-23
主线程-34
线程1-24
主线程-35
线程1-25
主线程-36
线程1-26
主线程-37
线程1-27
主线程-38
线程1-28
主线程-39
线程1-29
主线程-40
线程1-30
主线程-41
线程1-31
主线程-42
线程1-32
主线程-43
线程1-33
主线程-44
主线程-45
线程1-34
主线程-46
线程1-35
主线程-47
线程1-36
线程1-37
线程1-38
线程1-39
线程1-40
线程1-41
线程1-42
线程1-43
线程1-44
线程1-45
线程1-46
线程1-47
线程1-48
线程1-49
主线程-48
主线程-49

我们可以看到,结果输出是无序的,所以可以得出,线程的执行是无序的,计算机是在多个线程中高速切换。

以上是第一种实现多线程的方法,但是有一点不好,因为要继承Thread类,所以如果新线程类想要再继承别的类就无法实现,因为Java语言是不允许多继承的,但是实现接口就没有这么多限制。所以我们就可以用到第二种方法,我们可以让新线程类实现Runnable接口

再创建一个新线程类

package Thread_Learn;

public class Thread_02 implements Runnable {
//创建Thread对象,用来调用getName方法
@Override
	public void run() {
	Thread th = new Thread();
	for(int i=0;i<50;i++) {
		System.out.println(th.getName()+i);
	}
}
	
}

可以看到这个类实现了Runnable接口,并创建了一个Thread对象来调用getName()方法。
我们再创建一个主方法

package Thread_Learn;

public class Main_02 {
public static void main(String[] args) {
	//创建一个新实现类的对象
	Thread_02 th_02 = new Thread_02();
	//创建一个Thread对象,将上面创建的新线程类的对象th_02作为参数传递给Thread对象
	Thread th = new Thread(th_02);
	//用Thread对象调用setName()方法和start()方法
	th.setName("线程1-");
	th.start();
	
	for(int i =0;i<50;i++) {
		System.out.println("主线程-"+i);
	}
}
}

看一下运行结果
主线程-0
Thread-10
Thread-11
Thread-12
Thread-13
主线程-1
Thread-14
主线程-2
Thread-15
主线程-3
Thread-16
主线程-4
Thread-17
主线程-5
Thread-18
主线程-6
Thread-19
Thread-110
主线程-7
Thread-111
主线程-8
Thread-112
主线程-9
主线程-10
Thread-113
Thread-114
Thread-115
主线程-11
Thread-116
主线程-12
Thread-117
主线程-13
Thread-118
主线程-14
Thread-119
主线程-15
Thread-120
主线程-16
Thread-121
主线程-17
Thread-122
Thread-123
主线程-18
Thread-124
主线程-19
主线程-20
主线程-21
主线程-22
主线程-23
主线程-24
主线程-25
主线程-26
主线程-27
主线程-28
主线程-29
主线程-30
主线程-31
主线程-32
主线程-33
主线程-34
Thread-125
Thread-126
Thread-127
主线程-35
Thread-128
主线程-36
Thread-129
主线程-37
Thread-130
主线程-38
Thread-131
Thread-132
Thread-133
Thread-134
Thread-135
Thread-136
Thread-137
Thread-138
Thread-139
Thread-140
Thread-141
Thread-142
Thread-143
Thread-144
Thread-145
Thread-146
Thread-147
Thread-148
Thread-149
主线程-39
主线程-40
主线程-41
主线程-42
主线程-43
主线程-44
主线程-45
主线程-46
主线程-47
主线程-48
主线程-49

我们发现,线程1的名字并没有传进去,这是怎么回事。原来是因为Thread类中的getName()是个静态方法
static Thread currentThread():返回当前线程对象
需要通过Thread类名直接调用
Thread th = Thread.currentThread()

所以我们只需要把代码修改一下即可

package Thread_Learn;

public class Thread_02 implements Runnable {
//创建Thread对象,用来调用getName方法

@Override
	public void run() {
	Thread th = Thread.currentThread();
	for(int i=0;i<50;i++) {
		System.out.println(th.getName()+i);
	}
}
	
}

此时可以看到正确的输出结果
主线程-0
线程1-0
主线程-1
线程1-1
主线程-2
线程1-2
主线程-3
线程1-3
主线程-4
线程1-4
主线程-5
线程1-5
主线程-6
线程1-6
主线程-7
线程1-7
主线程-8
主线程-9
主线程-10
主线程-11
线程1-8
线程1-9
线程1-10
线程1-11
线程1-12
线程1-13
线程1-14
线程1-15
线程1-16
线程1-17
线程1-18
线程1-19
主线程-12
主线程-13
主线程-14
主线程-15
主线程-16
主线程-17
主线程-18
主线程-19
主线程-20
线程1-20
线程1-21
线程1-22
线程1-23
线程1-24
线程1-25
线程1-26
线程1-27
线程1-28
线程1-29
线程1-30
线程1-31
线程1-32
主线程-21
主线程-22
主线程-23
主线程-24
主线程-25
主线程-26
主线程-27
主线程-28
主线程-29
主线程-30
线程1-33
主线程-31
主线程-32
主线程-33
线程1-34
线程1-35
主线程-34
主线程-35
线程1-36
线程1-37
线程1-38
线程1-39
线程1-40
主线程-36
主线程-37
主线程-38
主线程-39
主线程-40
主线程-41
主线程-42
主线程-43
线程1-41
主线程-44
主线程-45
线程1-42
线程1-43
线程1-44
线程1-45
线程1-46
线程1-47
线程1-48
线程1-49
主线程-46
主线程-47
主线程-48
主线程-49

以上就是创建Java多线程的两种方法,当新线程类不需要继承其他类的时候可以使用第一种继承Thread类的方法。
当新线程类需要继承其他类的时候只能使用第二种实现Runnable接口,再将新继承类对象传递给Thread对象调用线程的方法。