博客
关于我
Java线程间的通信
阅读量:399 次
发布时间:2019-03-05

本文共 7644 字,大约阅读时间需要 25 分钟。

Java线程通信机制详解

在Java编程中,线程之间的通信是非常重要的一部分。特别是在多线程环境下,如何实现线程之间的协作和数据传递,是开发者需要解决的核心问题。以下将深入探讨Java线程通信的几种主要方法,包括锁、等待/通知机制、信号量、管道以及ThreadLocal类。


1. 锁与同步

在Java中,锁是实现线程安全的基础机制。锁的概念基于对象,称为对象锁。每个对象都有一个锁,只有持有这个锁的线程才能执行同步块中保护的代码。

示例代码

package chapter7;public class ObjectLock {    private static Object lock = new Object();    static class ThreadA implements Runnable {        @Override        public void run() {            synchronized (lock) {                System.out.println(lock);                for (int i = 0; i < 100; i++) {                    System.out.println("Thread A " + i);                }            }        }    }    static class ThreadB implements Runnable {        @Override        public void run() {            synchronized (lock) {                System.out.println(lock);                for (int i = 0; i < 100; i++) {                    System.out.println("Thread B " + i);                }            }        }    }    public static void main(String[] args) throws InterruptedException {        new Thread(new ThreadA()).start();        Thread.sleep(10);        new Thread(new ThreadB()).start();    }}

说明

  • 对象锁:每个对象都有一个独特的锁,这个锁可以由多个线程共享。只要一个线程持有锁,其他线程就无法进入同步块。
  • synchronized关键字:用于标记同步块,确保在同一时间内只有一个线程可以执行该块的代码。
  • 线程安全:通过锁的机制,Java保证了多线程程序在共享资源时的线程安全,避免了竞态条件和死锁。

2. 等待/通知机制 (wait()、notify()和notifyAll())

在Java中,基于锁的线程通信还支持等待/通知机制。这种机制允许线程在等待某个信号时进入WAITING状态,等待其他线程的通知。

notify()和notifyAll()

  • notify():随机唤醒一个正在等待的线程。
  • notifyAll():唤醒所有正在等待的线程。

示例代码

package chapter7;public class WaitAndNotify {    private static Object lock = new Object();    static class ThreadA implements Runnable {        @Override        public void run() {            synchronized (lock) {                System.out.println(lock);                for (int i = 0; i < 5; i++) {                    try {                        System.out.println("ThreadA: " + i);                        lock.notify();                        lock.wait();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }                lock.notify();            }        }    }    static class ThreadB implements Runnable {        @Override        public void run() {            synchronized (lock) {                System.out.println(lock);                for (int i = 0; i < 5; i++) {                    try {                        System.out.println("ThreadB: " + i);                        lock.notify();                        lock.wait();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }                lock.notify();            }        }    }    public static void main(String[] args) throws InterruptedException {        new Thread(new ThreadA()).start();        Thread.sleep(10);        new Thread(new ThreadB()).start();    }}

说明

  • 等待与通知:通过wait()notify()方法,线程可以暂时释放锁,等待其他线程的通知。这种机制非常适用于多线程程序中需要协作的场景。
  • 主动等待:如果没有其他线程主动调用notify(),当前线程将一直处于等待状态,直到被唤醒。

3. 信号量 (Semaphore)

Java提供了Semaphore类来实现信号量通信。信号量机制允许多个线程竞争资源,并在适当的时候允许某些线程继续执行。

示例代码

package chapter7;public class MySignal {    private static volatile int signal = 0;    private static final Object lock = new Object();    static class ThreadA implements Runnable {        @Override        public void run() {            while (signal < 5) {                if (signal % 2 == 0) {                    System.out.println("ThreadA: " + signal);                    synchronized (lock) {                        signal++;                    }                }            }        }    }    static class ThreadB implements Runnable {        @Override        public void run() {            while (signal < 5) {                if (signal % 2 == 1) {                    System.out.println("ThreadB: " + signal);                    synchronized (lock) {                        signal++;                    }                }            }        }    }    public static void main(String[] args) throws InterruptedException {        new Thread(new ThreadA()).start();        Thread.sleep(100);        new Thread(new ThreadB()).start();    }}

说明

  • 信号量机制:通过Semaphore类,程序可以管理资源的使用和线程的竞争。例如,上面的代码中,signal变量用来控制线程的执行顺序。
  • volatile关键字:确保多线程环境下变量的可见性和一致性。

4. 管道 (Pipes)

管道是一种基于内存的通信机制,适用于不同线程之间的数据传输。Java提供了基于字符流和字节流的管道实现。

示例代码

import java.io.IOException;import java.io.PipedReader;import java.io.PipedWriter;public class Pipe {    static class ReaderThread implements Runnable {        private PipedReader reader;        public ReaderThread(PipedReader reader) {            this.reader = reader;        }        @Override        public void run() {            System.out.println("this is reader");            int receive = 0;            try {                while ((receive = reader.read()) != -1) {                    System.print((char) receive);                }            } catch (IOException e) {                e.printStackTrace();            }        }    }    static class WriterThread implements Runnable {        private PipedWriter writer;        public WriterThread(PipedWriter writer) {            this.writer = writer;        }        @Override        public void run() {            System.out.println("this is writer");            try {                writer.write("test");            } catch (IOException e) {                e.printStackTrace();            } finally {                try {                    writer.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }    public static void main(String[] args) throws IOException, InterruptedException {        PipedWriter writer = new PipedWriter();        PipedReader reader = new PipedReader();        writer.connect(reader);        new Thread(new ReaderThread(reader)).start();        Thread.sleep(10);        new Thread(new WriterThread(writer)).start();    }}

说明

  • 字符流管道PipedReaderPipedWriter基于字符流实现通信,适用于字符数据的传输。
  • 连接机制:通过writer.connect(reader),实现了读写器之间的连接,允许数据流动。

5. ThreadLocal类

ThreadLocal类用于线程本地存储,确保每个线程都有自己的独立副本变量。这种机制特别适用于需要线程隔离的场景,如数据库连接管理。

示例代码

package chapter7;public class ThreadLocalDemo {    static class ThreadA implements Runnable {        private ThreadLocal
threadLocal; public ThreadA(ThreadLocal
threadLocal) { this.threadLocal = threadLocal; } @Override public void run() { threadLocal.set("A"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("ThreadA out: " + threadLocal + " -> content: " + threadLocal.get()); } } static class ThreadB implements Runnable { private ThreadLocal
threadLocal; public ThreadB(ThreadLocal
threadLocal) { this.threadLocal = threadLocal; } @Override public void run() { threadLocal.set("B"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("ThreadB out: " + threadLocal + " -> content: " + threadLocal.get()); } } public static void main(String[] args) { ThreadLocal
threadLocal = new ThreadLocal
(); new Thread(new ThreadA(threadLocal)).start(); new Thread(new ThreadB(threadLocal)).start(); }}

说明

  • 线程本地存储:每个线程都有自己独立的ThreadLocal对象,确保线程之间的隔离。
  • 线程安全:通过ThreadLocal机制,避免了共享状态引发的线程安全问题。

总结

Java提供了丰富的线程通信机制,包括锁、等待/通知机制、信号量、管道和ThreadLocal类。选择合适的通信机制,能够有效地实现多线程程序的设计需求。在实际开发中,根据具体场景选择合适的方法,才能实现高效且安全的线程通信。

转载地址:http://luczz.baihongyu.com/

你可能感兴趣的文章
Objective-C实现shortest job first短作业优先算法(附完整源码)
查看>>
Objective-C实现shortestCommonSupersequence最短公共超序列算法(附完整源码)
查看>>
Objective-C实现sierpinski triangle谢尔宾斯基三角形算法(附完整源码)
查看>>
Objective-C实现sieve of Eratosthenes埃拉托色尼筛法算法(附完整源码)
查看>>
Objective-C实现SieveOfEratosthenes埃拉托色尼筛法打印所有素数算法(附完整源码)
查看>>
Objective-C实现sieveOfEratosthenes埃拉托色尼筛法求素数算法 (附完整源码)
查看>>
Objective-C实现sieveOfEratosthenes埃拉托色尼筛选法算法(附完整源码)
查看>>
Objective-C实现sigmoid函数功能(附完整源码)
查看>>
Objective-C实现Sigmoid函数算法(附完整源码)
查看>>
Objective-C实现similarity search相似性搜索算法(附完整源码)
查看>>
Objective-C实现simple binary search简单的二分查找算法(附完整源码)
查看>>
Objective-C实现simpson approx辛普森算法(附完整源码)
查看>>
Objective-C实现simpson rule辛普森法则算法(附完整源码)
查看>>
Objective-C实现simulated annealing模拟退火算法(附完整源码)
查看>>
Objective-C实现SinglyLinkedList单链表算法(附完整源码)
查看>>
Objective-C实现SizeBalancedTree大小平衡树(附完整源码)
查看>>
Objective-C实现skew heap倾斜堆算法(附完整源码)
查看>>
Objective-C实现Skip List跳表算法(附完整源码)
查看>>
Objective-C实现slack message松弛消息算法(附完整源码)
查看>>
Objective-C实现SlopeOne算法(附完整源码)
查看>>