当前位置: 首页 > 技术教程

Java 多线程怎么创建? 线程同步用什么关键字?

  多线程是Java实现并发执行的核心机制,它允许程序同时运行多个独立的执行流(线程),从而提高 CPU 利用率,适用于需要处理多个任务的场景(如网络请求处理、数据并行计算等)。多线程共享资源时可能出现数据不一致问题,线程同步技术正是解决这一问题的关键。了解多线程的创建方法和同步关键字的使用,是掌握并发编程的基础。

  一、Java 多线程的创建方法

  Java 中创建线程主要有三种方式:继承Thread类、实现Runnable接口、实现Callable接口(带返回值),其中前两种最为常用。

  (一)继承 Thread 类

  Thread类是 Java 线程的基础类,继承该类并重写run()方法即可定义线程任务,通过start()方法启动线程(而非直接调用run())。

  示例:

  // 自定义线程类class MyThread extends Thread { @Override public void run() { // 线程执行的任务 for (int i = 0; i < 5; i++) { System.out.println("线程" + Thread.currentThread().getName() + ":" + i); } }}// 测试public class ThreadTest { public static void main(String[] args) { MyThread thread1 = new MyThread(); MyThread thread2 = new MyThread(); thread1.setName("Thread-1"); thread2.setName("Thread-2"); thread1.start(); // 启动线程1 thread2.start(); // 启动线程2 }}

  特点:实现简单,但因 Java 单继承限制,该类无法再继承其他类,灵活性较低。

  (二)实现 Runnable 接口

  Runnable接口仅定义了run()方法,实现该接口并重写方法后,需将实例传入Thread类的构造方法启动线程。

  示例:

  // 实现Runnable接口class MyRunnable implements Runnable { @Override public void run() { // 线程执行的任务 for (int i = 0; i < 5; i++) { System.out.println("线程" + Thread.currentThread().getName() + ":" + i); } }}// 测试public class RunnableTest { public static void main(String[] args) { MyRunnable task = new MyRunnable(); Thread thread1 = new Thread(task, "Thread-1"); Thread thread2 = new Thread(task, "Thread-2"); thread1.start(); thread2.start(); }}

  特点:避免单继承限制,多个线程可共享同一个Runnable实例(适合多线程共享资源场景),是更推荐的方式。

  (三)实现 Callable 接口(带返回值)

  Callable接口与Runnable类似,但call()方法可返回结果并抛出异常,需结合FutureTask类获取返回值。

  示例:

  import java.util.concurrent.Callable;import java.util.concurrent.FutureTask;// 实现Callable接口class MyCallable implements Callable<Integer> { @Override public Integer call() throws Exception { int sum = 0; for (int i = 1; i <= 10; i++) { sum += i; } return sum; // 返回计算结果 }}// 测试public class CallableTest { public static void main(String[] args) throws Exception { MyCallable task = new MyCallable(); FutureTask<Integer> futureTask = new FutureTask<>(task); Thread thread = new Thread(futureTask); thread.start(); System.out.println("计算结果:" + futureTask.get()); // 获取返回值 }}

  特点:适合需要线程返回结果的场景(如并行计算),但实现稍复杂。

java3.jpg

  二、线程同步的关键字:synchronized

  多线程共享资源时,若多个线程同时修改资源,可能导致数据错误(如银行账户并发取款)。synchronized关键字是 Java 中最基础的线程同步机制,通过加锁保证同一时间只有一个线程执行特定代码块,从而保护共享资源。

  (一)synchronized 的使用方式

  修饰方法:锁住当前对象实例(非静态方法)或类(静态方法)。

  class Counter { private int count = 0; // 非静态同步方法:锁住当前Counter实例 public synchronized void increment() { count++; } // 静态同步方法:锁住Counter类 public static synchronized void staticMethod() { // 静态资源操作 }}

  修饰代码块:锁住指定对象(更灵活,可减少锁范围)。

  class Counter { private int count = 0; private Object lock = new Object(); // 自定义锁对象 public void increment() { // 同步代码块:锁住lock对象 synchronized (lock) { count++; } }}

  (二)同步原理

  synchronized通过对象监视器(Monitor) 实现锁机制:

  线程进入同步代码前需获取锁,执行完毕后释放锁;

  若锁被其他线程占用,当前线程会进入阻塞状态,直至锁释放。

  这种机制保证了同步代码块的原子性(不可分割),避免多线程并发修改导致的数据不一致。

  (三)适用场景

  多线程共享简单资源(如计数器、共享变量);

  对同步性能要求不极致的场景(synchronized在 JDK 1.6 后经过优化,性能已大幅提升)。

  示例:解决并发计数问题

  // 未同步的计数器(存在问题)class UnsafeCounter { private int count = 0; public void increment() { count++; } public int getCount() { return count; }}// 同步的计数器(正确)class SafeCounter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; }}// 测试public class SyncTest { public static void main(String[] args) throws InterruptedException { SafeCounter counter = new SafeCounter(); // 10个线程同时递增 for (int i = 0; i < 10; i++) { new Thread(() -> { for (int j = 0; j < 1000; j++) { counter.increment(); } }).start(); } Thread.sleep(1000); // 等待所有线程执行完毕 System.out.println("最终计数:" + counter.getCount()); // 输出10000(正确) }}

  三、使用多线程的注意事项

  避免过度同步:同步范围过大(如同步整个方法)会导致线程阻塞时间长,降低并发效率,应尽量缩小同步代码块范围。

  防止死锁:多线程持有多个锁时,若获取顺序不一致可能导致死锁(如线程 1 持有锁 A 等待锁 B,线程 2 持有锁 B 等待锁 A),需保证锁的获取顺序一致。

  线程池优先:频繁创建和销毁线程会消耗资源,实际开发中建议使用线程池(如ExecutorService)管理线程生命周期。

  Java 多线程的创建可根据需求选择继承Thread、实现Runnable或Callable,其中Runnable因灵活性更常用;synchronized关键字是实现线程同步的基础,通过加锁机制保护共享资源。掌握这些知识,能帮助开发者应对简单的并发场景,为学习更高级的并发工具(如Lock、Atomic类)奠定基础。

 


猜你喜欢