📜  Java-多线程(1)

📅  最后修改于: 2023-12-03 15:31:34.619000             🧑  作者: Mango

Java-多线程

什么是多线程?

在计算机科学中,线程(英语:Thread)是在进行中的程序(控制单元),是比进程更小的执行单位,线程是进程的一部分,一个进程可以拥有多个线程。

多线程是指一个程序可以同时执行多个线程,这些线程可以在同一时间运行,也可以轮流运行,它提高了程序的执行效率,提高了计算机资源的利用率。

为什么使用多线程?

多线程的主要目的是提高程序的执行效率。当程序需要执行单个任务时,单线程就足够了。但是,当程序要执行多个任务时,如果只用单线程去执行,会出现单线程长时间占用处理器资源的情况,导致其他任务无法执行,影响程序的执行效率。使用多线程可以避免这个问题,将任务分配到多个线程中去执行,提高了程序的执行效率。

Java中实现多线程的方式

Java中支持多线程编程,Java中实现多线程的方式主要有两种:继承Thread类和实现Runnable接口。

使用Thread类实现多线程

使用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接口实现多线程,可以实现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接口

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();
        }
    }
}
多线程的优缺点
优点
  1. 大幅提升程序的执行效率

  2. 提高了程序的吞吐量

  3. 提升了计算机资源利用率

缺点
  1. 调试困难

  2. 多线程之间的并发访问会引发线程安全问题

  3. 需要消耗更多的系统资源

线程安全问题

多线程可能会引发线程安全问题,其中最常见的问题是:

1.变量在线程之间共享

多个线程可能会同时访问同一个变量,如果没有同步机制,可能会引发数据竞争的问题,从而导致结果出错。

2.多个线程之间的相互依赖

多个线程可能会相互依赖,其中一个线程必须等待另一个线程运行完毕才能继续执行,如果没有同步机制,会出现死锁的情况。

线程同步

为解决线程安全的问题,Java提供了线程同步的机制。线程同步可以保证多个线程同时访问共享资源时的安全性,Java提供了以下几种线程同步机制:

1.synchronized关键字

synchronized关键字是Java提供的最基本的同步机制,用于协调线程的运行,本质上是在java对象和线程之间建立一个监视器锁定,以保证线程的安全性。

public synchronized void doSomething() {
    // 线程执行的代码
}
2.wait和notify方法

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();
        }
    }
}
3.Lock机制

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();
        }
    }
}
Conclusion

Java中多线程是程序提高执行效率的重要手段,通过多线程可以同时运行多个任务,提高程序的处理性能。Java提供了多种实现多线程的方式,包括继承Thread类和实现Runnable接口等,同时还提供了多种线程同步机制,如synchronized关键字、wait和notify方法、Lock机制等,用于解决线程安全问题。需要注意的是,多线程开发不仅需要注意线程安全问题,还需要关注调试等问题。