会员可以在此提问,百战程序员老师有问必答
对大家有帮助的问答会被标记为“推荐”
看完课程过来浏览一下别人提的问题,会帮你学得更全面
截止目前,同学们一共提了 133647个问题
JAVA 全系列/第二阶段:JAVA 基础深化和提高/手写服务器项目(旧) 3691楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/反射技术(旧) 3693楼

老师,我的输出结果  为什么没有服务器收到了!

图片.png

图片.png

以下是服务器端的代码:

package ClientServer;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    public static void main(String[] args) throws IOException {
        System.out.println("--------服务器已启动--------");
        /**
         * 创建ServerSocket对象
         */
        ServerSocket server = new ServerSocket(8877);
        /**
         * 监听是否有客户端连接
         */
        Socket socket = server.accept();
        /**
         * 获取输入流数据
         */
        DataInputStream dis = new DataInputStream(socket.getInputStream());
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        while(true) {
            String str = dis.readUTF();
            System.out.println("客户端发送的数据为:"+str);
            /**
             * 获取输出流响应客户端的请求
             */
            dos.writeUTF("服务器端收到了:"+str);
        }
        /**
         * 关闭流
         */
        //CloseUtil.closeAll(dos,dis,socket);
    }

}

以下为客户端代码:

package ClientServer;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class ChatClient {
    public static void main(String[] args) throws UnknownHostException, IOException {
        /**
         * 创建Socket对象
         */
        Socket client = new Socket("localhost",8877);
        /**
         * 创建发送的线程类对象
         */
        Send send = new Send(client);
        /**
         * 创建接收的线程类对象
         */
        Receive receive = new Receive(client);
        /**
         * 创建Thread类并启动线程
         */
        new Thread(send).start();
        new Thread(receive).start();
        
    }
}


JAVA 全系列/第二阶段:JAVA 基础深化和提高/网络编程(旧) 3694楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/容器(旧) 3696楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/网络编程(旧) 3699楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/容器(旧) 3701楼

package com.itbaizhan;

class manTou{
    private int id;

    public void setId(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }
}

//定义缓冲区 不是线程类
class SyncStack{
    //定义放馒头的容器
    private manTou m[] = new manTou[10];

    //索引
    int i;

    //放馒头
    public synchronized void push(manTou mantou){
        //判断是否满了
        while(i == m.length) {  //用while多判断几次防止当前线程没有执行而忽略
            try {
                this.wait(); //object类的方法,必须在syn调用,线程的对象锁解放,并且进入堵塞状态
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        this.notify();  //唤醒等待序列中的一个线程
        this.m[i] = mantou;
        i++;

    }

    //取馒头
    public synchronized manTou pop() {
        //判断是否满了
        while (i == 0) {  //用while多判断几次防止当前线程没有执行而忽略
            try {
                this.wait(); //object类的方法,必须在syn调用,线程的对象锁解放,并且进入堵塞状态
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        this.notify();  //唤醒等待序列中的一个线程
        i--;
        return m[i];

    }

}

//定义生产者线程
class shengchan extends Thread{
    private SyncStack s;

    public shengchan(SyncStack s) {
        this.s = s;
    }

    @Override
    public void run() {
        for(int i = 0; i<10; i++){
            System.out.println("生产馒头" + i);
            manTou m = new manTou(); // 每次循环都创建一个新的馒头并放入stack里

            s.push(m);

        }
    }
}

class xiaofei extends Thread{
    private SyncStack s;

    public xiaofei(SyncStack s) {
        this.s = s;
    }

    @Override
    public void run() {
        for(int i = 0; i < 10; i++){
            System.out.println("取馒头" + i);
            manTou m = s.pop();

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class ProducerThread {
    public static void main(String[] args) {
        //创建缓冲区
        SyncStack s = new SyncStack();

        //创建生产线程
        shengchan produce = new shengchan(s);
        produce.start();

        //创建消费线程
        xiaofei consumer = new xiaofei(s);
        consumer.start();

    }
}

QQ图片20230207232704.png

这里两个线程锁的都是同一个对象,那按理说应该等生产线程执行完再执行消费啊,为什么还是并发执行的?

JAVA 全系列/第二阶段:JAVA 基础深化和提高/多线程技术 3704楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/常用类 3705楼

课程分类

百战程序员微信公众号

百战程序员微信小程序

©2014-2025百战汇智(北京)科技有限公司 All Rights Reserved 北京亦庄经济开发区科创十四街 赛蒂国际工业园
网站维护:百战汇智(北京)科技有限公司
京公网安备 11011402011233号    京ICP备18060230号-3    营业执照    经营许可证:京B2-20212637