两个线程间的通信

两个线程间的通信

  • 1.什么时候需要通信
    • 多个线程并发执行时,在默认情况下CPU是随机切换线程的。
    • 如果我们希望他们有规律的执行,就可以使用通信,例如每个线程执行一次打印。
  • 2.怎么通信
    • 如果希望线程等待,就调用wait()
    • 如果希望唤醒等待的线程,就调用notify()
    • 这两个方法必须在同步代码中执行,并且使用同步锁对象来调用
package com.heima.thread2;

public class Demo01_Notify {

	/**
	 * @param args
	 * 等待唤醒机制
	 */
	public static void main(String[] args) {
		final Printer p = new Printer();
		
		new Thread() {
			public void run() {
				while(true) {
					try {
						p.print1();
					} catch (InterruptedException e) {
						
						e.printStackTrace();
					}
				}
			}
		}.start();
		
		new Thread() {
			public void run() {
				while(true) {
					try {
						p.print2();
					} catch (InterruptedException e) {
						
						e.printStackTrace();
					}
				}
			}
		}.start();
	}

}

//等待唤醒机制
class Printer {
	private int flag = 1;
	public void print1() throws InterruptedException {							
		synchronized(this) {
			if(flag != 1) {
				this.wait();					//当前线程等待
			}
			System.out.print("黑");
			System.out.print("马");
			System.out.print("程");
			System.out.print("序");
			System.out.print("员");
			System.out.print("\r\n");
			flag = 2;
			this.notify();						//随机唤醒单个等待的线程
		}
	}
	
	public void print2() throws InterruptedException {
		synchronized(this) {
			if(flag != 2) {
				this.wait();
			}
			System.out.print("传");
			System.out.print("智");
			System.out.print("播");
			System.out.print("客");
			System.out.print("\r\n");
			flag = 1;
			this.notify();
		}
	}
}
<think>好的,我现在需要回答用户关于两个线程间通过socket通信的问题。用户之前提到的是线程间通信,而引用的资料主要涉及Java和C的Socket通信,以及多线程处理客户端连接。但用户现在的问题是两个线程之间,可能是在同一进程内或不同进程间?需要先明确。 首先,线程间通信通常不推荐用Socket,因为线程共享内存,使用共享变量或队列更高效。不过用户明确要求用Socket,可能是在模拟不同进程或不同机器的情况,或者有特殊需求。需要说明这一点,并给出示例。 接下来,引用中的资料有Java和C的例子。用户的问题可能偏向于Java,因为之前的引用较多关于Java。但需要确认。用户提供的示例有Python代码,但用户现在的需求是线程间Socket通信,可能不限制语言,但需要根据引用中的资料来调整。 引用1和2提到Java的多线程Socket通信,服务器处理多个客户端。但线程间通信可能需要创建客户端和服务器端分别在两个线程中运行。例如,一个线程作为服务器,另一个作为客户端,通过本地回环地址(127.0.0.1)通信。这样,虽然线程在同一台机器,但通过Socket通信,类似于进程间通信。 需要编写示例代码。可能用Java,因为引用中有相关内容。例如,创建一个服务器线程监听端口,另一个客户端线程连接并发送消息。需要注意端口占用和线程启动顺序。 另外,引用3提到了socket本地多进程通信,使用AF_UNIX或AF_INET。如果是同一台机器,可以使用本地地址,如127.0.0.1,或者Unix域套接字。但Java中可能不支持Unix域套接字,所以使用TCP Socket更合适。 需要确保代码正确,比如服务器先启动,客户端后连接。同时,处理异常和资源关闭。此外,多线程环境下,确保同步和避免竞争条件,但在此例中可能不需要,因为Socket本身是阻塞的,会自然同步。 然后,用户可能需要代码示例,分步骤解释。需要说明每个部分的作用,如ServerSocket、Socket、输入输出流的处理。同时,指出虽然线程间通信通常不用Socket,但此方法适用于模拟或特定场景。 最后,生成相关问题,可能涉及性能优化、其他通信方式比较、错误处理等。确保问题与主题相关,帮助用户深入理解。</think>### 两个线程间通过Socket通信的实现方法 线程间通过Socket通信的核心思路是:**将两个线程分别作为客户端和服务端,通过本地回环地址(127.0.0.1)进行数据交换**。尽管线程间通常使用共享内存或队列通信更高效,但Socket方式适用于模拟分布式通信或解耦场景[^1][^2]。 --- ### 代码示例(Java实现) #### 1. 服务端线程 ```java public class ServerThread implements Runnable { @Override public void run() { try (ServerSocket serverSocket = new ServerSocket(8888); Socket clientSocket = serverSocket.accept(); BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) { System.out.println("服务端已启动,等待消息..."); String message = in.readLine(); System.out.println("收到客户端消息: " + message); } catch (IOException e) { e.printStackTrace(); } } } ``` #### 2. 客户端线程 ```java public class ClientThread implements Runnable { @Override public void run() { try (Socket socket = new Socket("127.0.0.1", 8888); PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) { System.out.println("客户端已连接"); out.println("Hello from client!"); } catch (IOException e) { e.printStackTrace(); } } } ``` #### 3. 启动线程 ```java public static void main(String[] args) { new Thread(new ServerThread()).start(); // 确保服务端先启动 try { Thread.sleep(500); } catch (InterruptedException e) {} new Thread(new ClientThread()).start(); } ``` --- ### 关键点说明 1. **本地回环地址**:使用`127.0.0.1`实现同一机器的通信,避免网络延迟。 2. **端口协调**:服务端监听端口需与客户端连接端口一致(此处为8888)。 3. **输入输出流**:通过`BufferedReader`和`PrintWriter`实现文本数据传输。 4. **线程启动顺序**:服务端线程需先启动以完成端口绑定[^2]。 --- ### 适用场景 - 需要模拟分布式系统组件间的通信。 - 多线程需要跨网络隔离(如安全沙箱环境)。 - 异步通信且需解耦线程依赖[^1][^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

左绍骏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值