线程问题

wangdong20 2012-06-28 07:27:08
代码如下
jtaServer.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
sendMessage = jtaServer.getText();
if(!sendMessage.isEmpty()){
output.print(jtaServer.getText());
flag = true;
}
} else {
}
}
});



class SendThread extends Thread{
SendThread(Socket socket){
while(true){
if(flag == false){ //程序一直停在这儿
yield();
}
else{
flag = false;
InetAddress inetAddress = socket.getInetAddress();
if(!sendMessage.isEmpty()){
jtaDisplay.append(inetAddress.getHostName() + "\t" + new Date() + "\n");
jtaDisplay.append(sendMessage);
}
}
}
}
}

在学习网络,想实现Client 和Server聊天
我的思路是在Client这里一发送消息,就显示在jtaDisplay = new JTextArea(); 上,就像QQ上一样,能看到彼此的通信记录
同样的从Server哪里接受信息,也显示在jtaDisplay上
jtaServer是JTextArea, 我希望通过jtaServer的事件监听改变flag的值, 从而使SendThread 能进行下去 ,
按理说flag改变为true,就应该能执行下去,但是总是停在这里,不知为何
...全文
188 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
MiceRice 2012-06-29
  • 打赏
  • 举报
回复
我的回复似乎丢了。

看你的程序没看出来,但你对OutputStream写入数据后,是否执行了 flush()?

另外,你所写入的信息,是否确定有分割符(如空格)和换行符(\n)?
wangdong20 2012-06-29
  • 打赏
  • 举报
回复
太感谢楼上二位的指点 问题解决了
MiceRice 2012-06-29
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]
没有执行flush()这样会有什么问题吗
[/Quote]

没有执行 flush(),意味着数据包不一定会被立即发送给对方。

为了提升网络IO效率,输入输出都是带缓冲区的,批量发送;而不是你写1个字节就立即发送1个字节。


8楼说的是对的,你对netIO的体系还不熟悉,导致设计上存在扭曲。
不过我并不想对你程序做结构性修改建议,毕竟是另一个方向的事情,而且关键还是自己先懂。
wangdong20 2012-06-29
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]
不好意思,看你的这代码我有些着急了,我知识想你更好,其实当初我也一样,慢慢来,加油!
[/Quote]
谢谢你的回复,我还有很多要学的
lych_0317 2012-06-29
  • 打赏
  • 举报
回复
不好意思,看你的这代码我有些着急了,我知识想你更好,其实当初我也一样,慢慢来,加油!
lych_0317 2012-06-29
  • 打赏
  • 举报
回复
你的程序真的没法评价!怎么会用到flag,为什么要暂停线程?
http://www.cnblogs.com/linzheng/archive/2011/01/23/1942328.html
http://daoyongyu.iteye.com/blog/265677
这是两个关于这方面的知识,你好好研究研究吧
wangdong20 2012-06-29
  • 打赏
  • 举报
回复
我把代码贴出出来,真心希望哪位好心人能帮忙看看
package ex30;

import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.Date;
import java.util.Scanner;
import java.awt.event.*;

public class Ex30_12Server extends JFrame{
private JTextArea jtaDisplay = new JTextArea();
private JTextArea jtaServer = new JTextArea();
private PrintWriter output;
private Scanner sc;
private String sendMessage = "";
boolean flag = false;

public static void main(String[] args) {
// TODO 自动生成方法存根
new Ex30_12Server();
}

public Ex30_12Server(){
setLayout(new GridLayout(2, 1, 5, 5));
jtaDisplay.setEditable(false);
jtaDisplay.setBorder(BorderFactory.createTitledBorder(
"Server to Client"));
jtaServer.setBorder(BorderFactory.createTitledBorder(
"Server"));
add(new JScrollPane(jtaDisplay));
add(new JScrollPane(jtaServer));
setTitle("Ex30_12Server");
setSize(500, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);

try{
ServerSocket serverSocket = new ServerSocket(8000);

Socket socket = serverSocket.accept();
output = new PrintWriter(socket.getOutputStream());
sc = new Scanner(socket.getInputStream());
new Thread(new SendTask(socket)).start();
new Thread(new ReceiveTask(socket)).start();
}
catch(Exception ex){
System.err.println(ex);
}

jtaServer.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
sendMessage = jtaServer.getText();
if(!sendMessage.isEmpty()){
output.print(jtaServer.getText());
flag = true;
}
} else {
}
}
});
}

// Define the thread class for send message
class SendTask implements Runnable{
private Socket socket;
public SendTask(Socket socket){
this.socket = socket;
}

public void run(){
while(true){
if(flag == false){
Thread.yield();
}
else{
flag = false;
InetAddress inetAddress = socket.getInetAddress();
if(!sendMessage.isEmpty()){
jtaDisplay.append(inetAddress.getHostName() + "\t" + new Date() + "\n");
jtaDisplay.append(sendMessage + "\n");
}
}
}

}
}

// Define the thread class for receive message
class ReceiveTask implements Runnable{
private Socket socket;

public ReceiveTask(Socket socket){
this.socket = socket;
}

public void run(){
while(true){
String receiveMessage = "";
if(!sc.hasNext()){
Thread.yield();
}
else{
while(sc.hasNextLine()){
receiveMessage += sc.nextLine();
}
InetAddress inetAddress = socket.getInetAddress();
if(!receiveMessage.isEmpty()){
jtaDisplay.append(inetAddress.getHostName() + "\t" + new Date() + "\n");
jtaDisplay.append(receiveMessage + "\n");
}
}
}
}
}
}

package ex30;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import java.util.*;
import java.io.*;
import java.net.*;

public class Ex30_12Client extends JFrame{
private JTextArea jtaDisplay = new JTextArea();
private JTextArea jtaClient = new JTextArea();
private PrintWriter output;
private Scanner sc;
private String sendMessage = "";
boolean flag = false;

public Ex30_12Client(){
setLayout(new GridLayout(2, 1, 5, 5));
jtaDisplay.setEditable(false);
jtaDisplay.setBorder(BorderFactory.createTitledBorder(
"Client to Server"));
jtaClient.setBorder(BorderFactory.createTitledBorder(
"Client"));
add(new JScrollPane(jtaDisplay));
add(new JScrollPane(jtaClient));
setTitle("Ex30_12Client");
setSize(500, 300);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);

try{
Socket socket = new Socket("localhost", 8000);
output = new PrintWriter(socket.getOutputStream());
sc = new Scanner(socket.getInputStream());
new Thread(new SendTask(socket)).start();
new Thread(new ReceiveTask(socket)).start();
}
catch (Exception ex){
System.err.println(ex);
}

jtaClient.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
sendMessage = jtaClient.getText();
if(!sendMessage.isEmpty()){
output.print(jtaClient.getText());
flag = true;
}
} else {
}
}
});
}

public static void main(String[] args) {
// TODO 自动生成方法存根
new Ex30_12Client();
}

// Define the thread class for send message
class SendTask implements Runnable{
private Socket socket;
public SendTask(Socket socket){
this.socket = socket;
}

public void run(){
while(true){
if(flag == false){
Thread.yield();
}
else{
flag = false;
InetAddress inetAddress = socket.getInetAddress();
if(!sendMessage.isEmpty()){
jtaDisplay.append(inetAddress.getHostName() + "\t" + new Date() + "\n");
jtaDisplay.append(sendMessage + "\n");
}
}
}

}
}

// Define the thread class for receive message
class ReceiveTask implements Runnable{
private Socket socket;

public ReceiveTask(Socket socket){
this.socket = socket;
}

public void run(){
while(true){
String receiveMessage = "";
if(!sc.hasNext()){
Thread.yield();
}
else{
while(sc.hasNextLine()){
receiveMessage += sc.nextLine();
}
InetAddress inetAddress = socket.getInetAddress();
if(!receiveMessage.isEmpty()){
jtaDisplay.append(inetAddress.getHostName() + "\t" + new Date() + "\n");
jtaDisplay.append(receiveMessage + "\n");
}
}
}
}
}
}

wangdong20 2012-06-29
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
我的回复似乎丢了。

看你的程序没看出来,但你对OutputStream写入数据后,是否执行了 flush()?

另外,你所写入的信息,是否确定有分割符(如空格)和换行符(\n)?
[/Quote]
有空格和\n,没有执行flush()这样会有什么问题吗
wangdong20 2012-06-28
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
突然发现,你的线程定义,完全错误呐。。。

应该是定义在 run() 函数中,然后用 start() 去启动它,你这样写直接把主线程给阻塞了吧?!
[/Quote]
照你说的改了,现在SendTask没问题,ReceiveTask有问题,能显示自己的聊天信息,不能显示对方的聊天信息
代码如下
try{
ServerSocket serverSocket = new ServerSocket(8000);

Socket socket = serverSocket.accept();
output = new PrintWriter(socket.getOutputStream());
sc = new Scanner(socket.getInputStream());
new Thread(new SendTask(socket)).start();
new Thread(new ReceiveTask(socket)).start();
}
catch(Exception ex){
System.err.println(ex);
}

class ReceiveTask implements Runnable{
private Socket socket;

public ReceiveTask(Socket socket){
this.socket = socket;
}

public void run(){
while(true){
String receiveMessage = "";
if(!sc.hasNext()){ //线程在这里停住了
Thread.yield();
}
else{
while(sc.hasNextLine()){
receiveMessage += sc.nextLine();
}
InetAddress inetAddress = socket.getInetAddress();
if(!receiveMessage.isEmpty()){
jtaDisplay.append(inetAddress.getHostName() + "\t" + new Date() + "\n");
jtaDisplay.append(receiveMessage + "\n");
}
}
}
}
}
tigercbc 2012-06-28
  • 打赏
  • 举报
回复
有才!
MiceRice 2012-06-28
  • 打赏
  • 举报
回复
突然发现,你的线程定义,完全错误呐。。。

应该是定义在 run() 函数中,然后用 start() 去启动它,你这样写直接把主线程给阻塞了吧?!
MiceRice 2012-06-28
  • 打赏
  • 举报
回复
检查过:
if (e.getKeyCode() == KeyEvent.VK_ENTER)
这里面确实执行过么?

另外,所引用的flag变量是同一个么?

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧