1、什么是多线程之间通讯? 多线程之间通讯,其实就是多个线程在操作同一个资源,但是操作的动作不同。 2、多线程之间通讯需求 需求:第一个线程写入(input)用户,另一个线程取读取(out)用户,实现写一个,读一个的操作。 代码演示如下: 共享资源实体类 class Res { public String userSex; public String userName; } 输入线程资源 class InpThread extends Thread { private Res res; p 在多线程编程中,线程间的通信是一个关键概念,特别是在并发执行任务时,当多个线程需要共享和操作同一资源时。多线程之间的通讯主要是为了协调各个线程对共享资源的访问,确保数据的一致性和完整性。在这个场景中,我们有一个简单的例子,涉及到两个线程:一个用于写入数据(InpThread),另一个用于读取数据(OutThread)。 我们需要了解线程不安全的问题。在给定的代码中,`InpThread`和`OutThread`都访问了共享的`Res`对象,没有进行同步控制。这会导致数据竞争,即`OutThread`可能在`InpThread`更新数据之前读取旧值,从而产生错误的输出。例如,`OutThread`可能会连续打印出“小明--男”,而期望的结果是交替打印“小明--男”和“小红--女”。 为了解决线程安全问题,我们通常会使用同步机制,如Java中的`synchronized`关键字。当在`InpThread`和`OutThread`的`run()`方法中使用`synchronized`关键字锁定`Res`对象时,每次只有一个线程能访问资源,从而避免了数据不一致。然而,虽然这样做解决了线程安全问题,但它并没有实现按顺序打印的预期效果。这是因为两个线程都在等待对方释放对资源的控制权,但它们并不会互相通知何时可以继续执行。 这时,我们可以利用`wait()`, `notify()`, 和`notifyAll()`这三个方法来控制线程的协作。这些方法定义在Java的`Object`类中,主要用于线程的等待和唤醒。`wait()`让当前线程释放锁并进入等待状态,直到其他线程调用`notify()`或`notifyAll()`来唤醒它。`notify()`只唤醒一个等待该对象的线程,而`notifyAll()`则唤醒所有等待的线程。 要实现交替打印,我们需要让写入线程写完数据后通知读取线程,而读取线程读完数据后等待写入线程。这是一个典型的生产者-消费者问题,可以使用条件变量或者`wait/notify`机制来解决。在`InpThread`中,写入数据后调用`res.notify()`;在`OutThread`中,读取数据前调用`res.wait()`,并在读取后再次调用`res.wait()`。这样,写入线程将唤醒读取线程,读取线程读完数据后会让出资源并等待下一次写入。 以下是修改后的代码示例: ```java class Res { public String userSex; public String userName; private boolean isWriting = false; synchronized void write(String userSex, String userName) throws InterruptedException { while (isWriting) { wait(); } this.userSex = userSex; this.userName = userName; isWriting = true; notify(); } synchronized void read() throws InterruptedException { while (!isWriting) { wait(); } System.out.println(userName + "--" + userSex); isWriting = false; notify(); } } class InpThread extends Thread { private Res res; public InpThread(Res res) { this.res = res; } @Override public void run() { try { while (true) { res.write("小明", "男"); res.write("小红", "女"); } } catch (InterruptedException e) { e.printStackTrace(); } } } class OutThread extends Thread { private Res res; public OutThread(Res res) { this.res = res; } @Override public void run() { try { while (true) { res.read(); } } catch (InterruptedException e) { e.printStackTrace(); } } } ``` 通过这种方式,我们可以确保写入线程写完数据后读取线程才会开始读取,实现了交替打印的效果。在实际开发中,还可以考虑使用更高级的并发工具,如`BlockingQueue`,来简化线程间通信的处理,提高代码的可读性和可维护性。
剩余6页未读,继续阅读
- 粉丝: 6
- 资源: 919
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助