📅  最后修改于: 2023-12-03 15:31:34.619000             🧑  作者: Mango
在计算机科学中,线程(英语:Thread)是在进行中的程序(控制单元),是比进程更小的执行单位,线程是进程的一部分,一个进程可以拥有多个线程。
多线程是指一个程序可以同时执行多个线程,这些线程可以在同一时间运行,也可以轮流运行,它提高了程序的执行效率,提高了计算机资源的利用率。
多线程的主要目的是提高程序的执行效率。当程序需要执行单个任务时,单线程就足够了。但是,当程序要执行多个任务时,如果只用单线程去执行,会出现单线程长时间占用处理器资源的情况,导致其他任务无法执行,影响程序的执行效率。使用多线程可以避免这个问题,将任务分配到多个线程中去执行,提高了程序的执行效率。
Java中支持多线程编程,Java中实现多线程的方式主要有两种:继承Thread类和实现Runnable接口。
使用Thread类实现多线程,可以继承Thread类,重写run方法,然后创建一个线程对象,调用thread.start()方法启动线程,线程开始执行run方法中的代码。
public class MyThread extends Thread {
@Override
public void run() {
// 线程执行的代码
}
}
public class Test {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
使用Runnable接口实现多线程,可以实现Runnable接口,重写run方法,然后创建一个线程对象,并传递Runnable对象,调用thread.start()方法启动线程,线程开始执行run方法中的代码。
public class MyRunnable implements Runnable {
@Override
public void run() {
// 线程执行的代码
}
}
public class Test {
public static void main(String[] args) {
MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start();
}
}
Callable接口是Java5新增的一个接口,实现此接口的类可以返回结果并且可以抛出异常,相当于Runnable接口的增强版,与Runnable接口不同的是,Callable接口中的call()方法可以返回执行结果,该方法可以抛出异常。
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class MyCallable implements Callable<String> {
@Override
public String call() {
// 线程执行的代码
return "线程执行完成!";
}
}
public class Test {
public static void main(String[] args) {
MyCallable myCallable = new MyCallable();
FutureTask<String> futureTask = new FutureTask<>(myCallable);
Thread thread = new Thread(futureTask);
thread.start();
try {
String result = futureTask.get();
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
} finally {
thread.interrupt();
}
}
}
大幅提升程序的执行效率
提高了程序的吞吐量
提升了计算机资源利用率
调试困难
多线程之间的并发访问会引发线程安全问题
需要消耗更多的系统资源
多线程可能会引发线程安全问题,其中最常见的问题是:
多个线程可能会同时访问同一个变量,如果没有同步机制,可能会引发数据竞争的问题,从而导致结果出错。
多个线程可能会相互依赖,其中一个线程必须等待另一个线程运行完毕才能继续执行,如果没有同步机制,会出现死锁的情况。
为解决线程安全的问题,Java提供了线程同步的机制。线程同步可以保证多个线程同时访问共享资源时的安全性,Java提供了以下几种线程同步机制:
synchronized关键字是Java提供的最基本的同步机制,用于协调线程的运行,本质上是在java对象和线程之间建立一个监视器锁定,以保证线程的安全性。
public synchronized void doSomething() {
// 线程执行的代码
}
wait()和notify()方法是Object类中提供的两个方法,可以实现线程的等待和通知机制,wait()方法让当前线程等待,release()方法唤醒所有等待的线程。
public class MyThread extends Thread {
@Override
public void run() {
synchronized (this) {
try {
System.out.println("线程等待中...");
wait();
System.out.println("线程被唤醒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Test {
public static void main(String[] args) {
MyThread thread = new MyThread();
synchronized (thread) {//这里如果是同步方法,可以在这里wait
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程唤醒线程");
thread.notify();
}
}
}
Lock机制是Java提供的一种高级同步机制,相对于synchronized关键字,Lock机制具备更好的性能和可伸缩性,除了可以解决线程安全问题外,还可以实现更多的功能,比如读写锁、公平锁、定时锁等。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyThread extends Thread {
private Lock lock = new ReentrantLock();
@Override
public void run() {
try {
lock.lock();
// 线程执行的代码
} finally {
lock.unlock();
}
}
}
Java中多线程是程序提高执行效率的重要手段,通过多线程可以同时运行多个任务,提高程序的处理性能。Java提供了多种实现多线程的方式,包括继承Thread类和实现Runnable接口等,同时还提供了多种线程同步机制,如synchronized关键字、wait和notify方法、Lock机制等,用于解决线程安全问题。需要注意的是,多线程开发不仅需要注意线程安全问题,还需要关注调试等问题。