创建多线程最常见一般使用两种方式,一种为继承Thread类,一种为实现Runnable接口。还有一些其他一些方式,下面为大家列出包括继承和实现的一共四种方式。
使用继承Thread类实现
继承Thread类是最简单实现多线程的一种,使用JDK自带的Thread类,重写类中的run()方法,然后通过start方法调用,下面代码简单的来实现使用继承方式实现多线程。
简单实现两个线程
package com.thread.java;
/**
* 使用继承方式来实现多线程
* 下面创建一个线程来输出1—20之间的偶数;
*/
class MyThread2 extends Thread{
private static int num = 1;
@Override
//重写run()方法
public void run() {
while(true){
try {
sleep(100); //线程休眠0.1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
if(num%2==0){
System.out.println(Thread.currentThread().getName()+":"+num);
}
num++;
if(num>=20)
break;
}
}
}
public class ThreadExtends2 {
public static void main(String[] args) {
//先创建两个线程
MyThread2 thread1 = new MyThread2();
MyThread2 thread2 = new MyThread2();
//改名为线程1和线程2
thread1.setName("线程1");
thread2.setName("线程2");
//开始线程1和线程2
thread1.start();
thread2.start();
}
}
使用synchronized方法线程同步监视器线程同步代码如下
package com.thread.java;
/**
* 使用继承方式来实现多线程
* 下面创建一个线程来输出1—20之间的偶数;
*/
class MyThread2 extends Thread{
private static int num = 1;
@Override
//重写run()方法
public void run() {
while(true) {
synchronized (this) { //线程同步监视,使用this作为对象
try {
sleep(100); //线程休眠0.1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
if (num % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ":" + num);
}
num++;
if (num >= 20)
break;
}
}
}
}
public class ThreadExtends2 {
public static void main(String[] args) {
//先创建两个线程
MyThread2 thread = new MyThread2();
Thread thread1 = new Thread(thread);
Thread thread2 = new Thread(thread);
//改名为线程1和线程2
thread1.setName("线程1");
thread2.setName("线程2");
//开始线程1和线程2
thread1.start();
thread2.start();
}
}
使用wait()方法和notify()方法实现线程交互
package com.thread.java;
/**
* 使用继承方式来实现多线程
* 下面创建一个线程来输出1—20之间的偶数;
*/
class MyThread2 extends Thread{
private static int num = 1;
Object obj = new Object();
@Override
//重写run()方法
public void run() {
while(true) {
synchronized (obj) {
obj.notify(); //唤醒线程,不过只能唤醒单个线程, 如果需要一次性唤醒多个线程可以使用notifyAll()方法
try {
sleep(100); //线程休眠0.1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
if (num % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ":" + num);
try {
obj.wait(); //使线程阻塞,等待唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
num++;
if (num > 20)
break;
}
}
}
}
public class ThreadExtends2 {
public static void main(String[] args) {
//先创建两个线程
MyThread2 thread = new MyThread2();
Thread thread1 = new Thread(thread);
Thread thread2 = new Thread(thread);
//改名为线程1和线程2
thread1.setName("线程1");
thread2.setName("线程2");
//开始线程1和线程2
thread1.start();
thread2.start();
}
}
使用实现Runnable接口方式创建多线程
实现Runnable接口方式创建多线程,并且使用线程监视方法实现线程同步。
package com.thread.java;
/**
* 使用实现接口Runnable方式来实现多线程
* 下面简单使用三个线程顺序交互输出1-20数字
*/
class MyThread3 implements Runnable{
Object obj = new Object();
private int num = 1;
@Override
public void run() {
while(true) {
if (!show()){
break;
}
}
}
//使用线程监视方法
private synchronized boolean show(){
if (num <= 20) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
printThreadName(num);
num++;
}else{
return false;
}
return true;
}
//封装输出,外面可以调用输出ticket值
public void printThreadName(int ticket){
System.out.println(Thread.currentThread().getName()+":"+ticket);
}
}
public class ThreadRunnable {
public static void main(String[] args) {
MyThread3 thread = new MyThread3();
//创建三个线程
Thread thread1 = new Thread(thread);
Thread thread2 = new Thread(thread);
Thread thread3 = new Thread(thread);
//三个线程名字分别命名
thread1.setName("线程1:");
thread2.setName("线程2:");
thread3.setName("线程3:");
//开始线程
thread1.start();
thread2.start();
thread3.start();
}
}
使用实现Callable接口和FutureTask类来实现多线程
Callable接口相较于Runnable接口拥有以下优势,Callable接口有返回值,并且支持泛型。
实现代码如下:
package com.thread.java;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
* 下面使用Callable接口,重写call方法。
* 创建Callable对象,然后以Callable对象作为参数传入futureTask对象内。
* 将futureTask对象作为Thread参数实现Thread线程
* 下列以输出一百以内的素数为例
*/
class NumThread implements Callable{
private static int num1 = 2;
@Override
public Object call() throws Exception {
while(true) {
int t = 1;
int num2 = num1 / 2;
while (num2 > 1) {
if (num1 % num2 != 0) {
num2--;
}else{
t=0;
break;
}
}
if (t==1){
System.out.println("线程为:"+Thread.currentThread().getName()+num1);
}
if(num1<100){
num1++;
}else{
break;
}
}
return num1;
}
}
public class CallableTest {
public static void main(String[] args) {
NumThread numThread = new NumThread();
FutureTask futureTask = new FutureTask(numThread);
new Thread(futureTask).start();
}
}
使用线程池创建多线程
很多时候我们每次执行一个任务就有一个线程,但是这个线程往往都在很短的时间内结束了,效率很低,然而线程池就会完美的解决此问题。
线程池使用方法代码如下:
package com.thread.java;
import java.lang.reflect.Executable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Threads {
public static void main(String[] args) {
//创建一个线程池,容量为5,并且添加一个刚才创建的一个线程。
ExecutorService pool = Executors.newFixedThreadPool(5);
Future f = pool.submit( new MyThread2() );
}
}
备注:新人作者,内容过于简要,需要改正的地方备注在评论区。