【JAVA多线程核心概念:线程的创建和同步】

111 阅读3分钟

创建线程的几种方式以及同步方式

在多线程编程中,合理地创建线程和同步线程是保证程序正确性和性能的关键。本文将详细介绍Java中创建线程的几种方式以及同步线程的几种方法,并提供相应的代码示例。

创建线程的几种方式

1. 继承Thread类

通过创建一个子类并重写run()方法来创建线程。

// 继承Thread类
class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " - Count: " + i);
            try {
                // 模拟工作,休眠500毫秒
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

// 主类
public class ThreadExample {
    public static void main(String[] args) {
        // 创建线程实例
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();
        // 启动线程
        thread1.start();
        thread2.start();
    }
}

2. 实现Runnable接口

通过实现Runnable接口并将其传递给Thread对象来创建线程。

// 实现Runnable接口
class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " - Count: " + i);
            try {
                // 模拟工作,休眠500毫秒
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

// 主类
public class RunnableExample {
    public static void main(String[] args) {
        // 创建Runnable实例
        MyRunnable myRunnable = new MyRunnable();
        // 创建Thread对象
        Thread thread1 = new Thread(myRunnable);
        Thread thread2 = new Thread(myRunnable);
        // 启动线程
        thread1.start();
        thread2.start();
    }
}

线程同步的几种方式

在多线程环境中,多个线程可能会同时访问共享资源,导致数据不一致。为了解决这个问题,Java提供了多种同步机制。

1. 使用synchronized关键字

使用synchronized关键字来修饰方法或代码块,确保同一时间只有一个线程可以执行被修饰的代码。

class Counter {
    private int count = 0;
    // 同步方法
    public synchronized void increment() {
        count++;
    }
    public int getCount() {
        return count;
    }
}

public class SynchronizedExample {
    public static void main(String[] args) {
        Counter counter = new Counter();
        // 创建多个线程
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        thread1.start();
        thread2.start();
        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Final count: " + counter.getCount());
    }
}

2. 使用ReentrantLock

ReentrantLock是Java提供的更灵活的锁机制,可以替代synchronized关键字,提供了更高级的功能。

import java.util.concurrent.locks.ReentrantLock;

class LockCounter {
    private int count = 0;
    private ReentrantLock lock = new ReentrantLock();
    public void increment() {
        lock.lock(); // 获取锁
        try {
            count++;
        } finally {
            lock.unlock(); // 释放锁
        }
    }
    public int getCount() {
        return count;
    }
}

public class ReentrantLockExample {
    public static void main(String[] args) {
        LockCounter lockCounter = new LockCounter();
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                lockCounter.increment();
            }
        });
        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                lockCounter.increment();
            }
        });
        thread1.start();
        thread2.start();
        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Final count: " + lockCounter.getCount());
    }
}

3. 使用Condition

Condition是与Lock配合使用的,用于线程间的协调。

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionExample {
    private final Lock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    private boolean ready = false;

    public void prepare() {
        lock.lock();
        try {
            System.out.println("Preparing data...");
            Thread.sleep(2000);
            ready = true;
            System.out.println("Data is ready.");
            condition.signal(); // 唤醒等待的线程
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void consume() {
        lock.lock();
        try {
            while (!ready) {
                System.out.println("Data is not ready yet. Waiting...");
                condition.await(); // 等待数据准备完毕
            }
            System.out.println("Data is ready. Consuming...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ConditionExample example = new ConditionExample();
        Thread producer = new Thread(() -> {
            example.prepare();
        });
        Thread consumer = new Thread(() -> {
            example.consume();
        });
        consumer.start();
        producer.start();
    }
}

以上是Java中创建线程和同步线程的几种方式,通过这些方法可以有效地管理多线程程序中的资源共享和线程调度问题。希望这些示例能够帮助你更好地理解和应用多线程编程。