Java高并发之多线程

本文详细介绍了多线程的概念,包括为何使用多线程以及在单核和多核CPU下的优势。通过实例展示了如何通过继承Thread类、实现Runnable接口以及使用Callable接口创建多线程,并讨论了不同实现方式的适用场景。最后提到了Java中的synchronized关键字在高并发环境中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、什么是多线程

进程中有多个线程,对于多核cpu来说,多个线程可以同时执行,提高了cpu的利用率。

2、为什么要用多线程

(1)从计算机底层来说:线程是轻量级的进程,是程序的最小执行单元;对于多核cpu而言,多个线程可以同时执行,减少了线程间切换的开销,即提高了cpu的利用率,同时也提高了程序的效率。
(2)从当前业务场景来说:目前动不动就要求百万级、千万级的并发量,而多线程正是开发高并发系统的基础。
(3)在单核时代,多线程主要是用来提高cpuIO设备的综合利用率。只有一个线程时,当cpu计算时,IO空闲,当IO操作时,cpu空闲,cpuIO的利用率是50%。但是如果有两个线程,一个线程执行cpu计算,一个线程执行IO操作,在理想情况下可以说利用率达到100%了。
(4)在多核时代,多线程主要是提高cpu的利用率,多个线程可以让多个cpu同时被使用,提高了cpu的利用率,同时也提高了程序的性能。

3、怎么使用多线程

(1)继承Thread类,实现多线程

package com.kk.first.thread;

public class TestThread extends Thread {
	
	private String name;
	
	public TestThread(String threadName) {
		this.name = threadName;
	}
	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println(name + "-" + i);
		}
	}
}
public class Test {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		test();
	}
	public static void test() {
		Thread t1 = new TestThread("线程1");
		Thread t2 = new TestThread("线程2");
		Thread t3 = new TestThread("线程3");
		t1.start();
		t2.start();
		t3.start();
	}
}

继承java.lang.Thread的程序类,重写run()方法,在run()方法中执行多线程的逻辑。(run()方法不能直接调用,启动线程必须通过start()方法)

(2)实现Runnable接口实现多线程

package com.kk.first.thread;

public class TestRunnable implements Runnable{
	
	private String name;
    public TestRunnable(String name) {
		this.name = name;
	}
	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println(name + "-" + i);
		}
	}
}
public class Test {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		test();
	}
	public static void test() {
		Thread t1 = new Thread(new TestRunnable("线程1"));
		Thread t2 = new Thread(new TestRunnable("线程2"));
		Thread t3 = new Thread(new TestRunnable("线程3"));
		t1.start();
		t2.start();
		t3.start();
	}
}

虽然通过继承Thread可以实现多线程,但是继承是有单继承限制的,不利于自定义的多线程类扩充其他的功能。而通过实现Runnable接口则没有这个限制。而且从Thread源码可以看出,Thread也是实现了Runnable接口,ThreadRunnable的子类。
在这里插入图片描述
多线程的设计用到了代理模式,用户自定义的线程主体只负责核心功能的实现,其他辅助逻辑则交给Thread来实现。
关于代理模式,可以看看这篇博文深入解析Java代理模式(静态代理和动态代理)

(3)实现Callable接口实现多线程

package com.kk.first.thread;

import java.util.concurrent.Callable;

public class TestCallable implements Callable<String>{

	@Override
	public String call() throws Exception {
		for (int i =0; i < 10; i++) {
			System.out.println("线程执行" + i);
		}
		return "线程执行完成";
	}
}
public class Test {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		test();
	}
	public static void test() throws InterruptedException, ExecutionException {
		FutureTask ft = new FutureTask(new TestCallable());
		Thread t = new Thread(ft);
		t.start();
		System.out.println(ft.get());
	}
}

一般开发多线程都用Runnable来实现,但是Runnable有一个缺点,当线程执行完后,无法获取一个返回值。所有在jdk1.5之后推出了java.util.concurrent.Callable接口来实现多线程,定义Callable的时候可以设置一个泛型,这个泛型就是返回值的类型。
通过Callable实现多线程,重写call()方法可以设置线程执行完后的返回值。
在这里插入图片描述
下篇博文:Java高并发之synchronized关键字

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值