java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java线程之间通信

Java线程之间通信的几种方式详解

作者:yymagicer

在 Java 中,线程之间的通信是通过共享内存模型来实现的,线程通过共享的对象和变量来交换数据,为了确保线程间通信的正确性,Java 提供了一系列机制来实现线程安全、同步和通信,以下是常用的几种线程间通信的方式,以及它们的使用方法和场景,需要的朋友可以参考下

1. 共享变量与同步机制

多个线程可以通过共享对象的变量进行通信,但为了避免数据不一致的问题,必须使用同步机制来控制对共享变量的访问。

class Counter {
    private int count = 0;
 
    public synchronized void increment() {
        count++;
    }
 
    public synchronized int getCount() {
        return count;
    }
}
 
public class SyncExample {
    public static void main(String[] args) {
        Counter counter = new Counter();
 
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
 
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
 
        t1.start();
        t2.start();
 
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
 
        System.out.println("Final count: " + counter.getCount());
    }
}
class Flag {
    private volatile boolean running = true;
 
    public void stop() {
        running = false;
    }
 
    public boolean isRunning() {
        return running;
    }
}
 
public class VolatileExample {
    public static void main(String[] args) {
        Flag flag = new Flag();
 
        Thread t1 = new Thread(() -> {
            while (flag.isRunning()) {
                System.out.println("Thread is running");
            }
            System.out.println("Thread stopped");
        });
 
        t1.start();
 
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
 
        flag.stop();
    }
}

2. wait()、notify() 和 notifyAll()

Object 类的这三个方法用于在同步块内实现线程间的协作。线程可以通过 wait() 进入等待状态,直到另一个线程调用 notify() 或 notifyAll() 唤醒它们。

示例:生产者-消费者模型

class SharedResource {
    private int value;
    private boolean hasValue = false;
 
    public synchronized void produce(int newValue) throws InterruptedException {
        while (hasValue) {
            wait(); // 等待消费者消费
        }
        value = newValue;
        hasValue = true;
        System.out.println("Produced: " + value);
        notify(); // 唤醒消费者
    }
 
    public synchronized void consume() throws InterruptedException {
        while (!hasValue) {
            wait(); // 等待生产者生产
        }
        System.out.println("Consumed: " + value);
        hasValue = false;
        notify(); // 唤醒生产者
    }
}
 
public class ProducerConsumerExample {
    public static void main(String[] args) {
        SharedResource resource = new SharedResource();
 
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 5; i++) {
                    resource.produce(i);
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
 
        Thread consumer = new Thread(() -> {
            try {
                for (int i = 0; i < 5; i++) {
                    resource.consume();
                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
 
        producer.start();
        consumer.start();
    }
}

使用场景:适用于线程间的协调工作,比如生产者-消费者模型,一个线程负责生产资源,另一个线程负责消费资源。

3. Lock 和 Condition 接口

相比 synchronizedLock 提供了更灵活的同步机制,而 Condition 可以替代 wait()notify() 和 notifyAll(),并支持多个等待条件。

示例:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
 
class BoundedBuffer {
    private final int[] buffer;
    private int count, in, out;
    private final Lock lock = new ReentrantLock();
    private final Condition notFull = lock.newCondition();
    private final Condition notEmpty = lock.newCondition();
 
    public BoundedBuffer(int size) {
        buffer = new int[size];
    }
 
    public void put(int value) throws InterruptedException {
        lock.lock();
        try {
            while (count == buffer.length) {
                notFull.await(); // 等待缓冲区未满
            }
            buffer[in] = value;
            in = (in + 1) % buffer.length;
            count++;
            notEmpty.signal(); // 唤醒消费线程
        } finally {
            lock.unlock();
        }
    }
 
    public int take() throws InterruptedException {
        lock.lock();
        try {
            while (count == 0) {
                notEmpty.await(); // 等待缓冲区非空
            }
            int value = buffer[out];
            out = (out + 1) % buffer.length;
            count--;
            notFull.signal(); // 唤醒生产线程
            return value;
        } finally {
            lock.unlock();
        }
    }
}
 
public class LockConditionExample {
    public static void main(String[] args) {
        BoundedBuffer buffer = new BoundedBuffer(5);
 
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    buffer.put(i);
                    System.out.println("Produced: " + i);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
 
        Thread consumer = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    int value = buffer.take();
                    System.out.println("Consumed: " + value);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
 
        producer.start();
        consumer.start();
    }
}

使用场景:适用于需要显式锁定、更复杂的条件等待场景,比如多条件同步、多生产者-消费者模型。

4. java.util.concurrent 包的并发工具

Java 提供了 java.util.concurrent 包下的一系列高级并发工具类来简化线程间通信。

到此这篇关于Java线程之间通信的几种方式详解的文章就介绍到这了,更多相关Java线程之间通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文