Java 全局共享整数

Java 全局共享整数,java,netty,Java,Netty,我正在学习Netty并尝试实现一个简单的计数器,其中所有客户机共享一个整数,他们输入一个数字,整数值按该数字递增 这是我的密码: Server.java package nettyincvalue; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; import io.netty.channel.Even

我正在学习
Netty
并尝试实现一个简单的计数器,其中所有客户机共享一个
整数
,他们输入一个数字,
整数
值按该数字递增

这是我的密码:

Server.java

package nettyincvalue;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Server {

    private int port;
    private Integer value;

    public Server(int port) {
        this.port = port;
        this.value = 0;
    }

    public void run(){

        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {

            ServerBootstrap server = new ServerBootstrap();

            server.group(bossGroup, workerGroup)
                  .channel(NioServerSocketChannel.class)
                  .childHandler(new ServerInit(this.value))
                  .option(ChannelOption.SO_BACKLOG, 128)
                  .childOption(ChannelOption.SO_KEEPALIVE, true);


            ChannelFuture f = server.bind(port).sync();

            f.channel().closeFuture().sync();


        } catch (InterruptedException ex) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }

    }

    public static void main(String[] args) {
        new Server(12345).run();
    }

}
package nettyincvalue;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.string.StringDecoder;

public class ServerInit extends ChannelInitializer<SocketChannel> {

    private Integer value;

    public ServerInit(Integer value) {
        this.value = value;
    }

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {

        ChannelPipeline pipeline = ch.pipeline();

        pipeline.addLast(new StringDecoder());
        pipeline.addLast(new ServerHandler(this.value));

    }

}
package nettyincvalue;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class ServerHandler extends ChannelInboundHandlerAdapter {

    private Integer value;

    public ServerHandler(Integer value) {
        this.value = value;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        String s = (String) msg;

        try {

            Integer i = Integer.parseInt(s.substring(0, s.length() - 1));
            this.value += i;
            System.out.println("Value its now: " + this.value);

        } catch (NumberFormatException n) {
            System.out.println("Not a number received");
        }

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.err.println(cause.getMessage());
        ctx.close();
    }
}
ServerInit.java

package nettyincvalue;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Server {

    private int port;
    private Integer value;

    public Server(int port) {
        this.port = port;
        this.value = 0;
    }

    public void run(){

        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {

            ServerBootstrap server = new ServerBootstrap();

            server.group(bossGroup, workerGroup)
                  .channel(NioServerSocketChannel.class)
                  .childHandler(new ServerInit(this.value))
                  .option(ChannelOption.SO_BACKLOG, 128)
                  .childOption(ChannelOption.SO_KEEPALIVE, true);


            ChannelFuture f = server.bind(port).sync();

            f.channel().closeFuture().sync();


        } catch (InterruptedException ex) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }

    }

    public static void main(String[] args) {
        new Server(12345).run();
    }

}
package nettyincvalue;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.string.StringDecoder;

public class ServerInit extends ChannelInitializer<SocketChannel> {

    private Integer value;

    public ServerInit(Integer value) {
        this.value = value;
    }

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {

        ChannelPipeline pipeline = ch.pipeline();

        pipeline.addLast(new StringDecoder());
        pipeline.addLast(new ServerHandler(this.value));

    }

}
package nettyincvalue;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class ServerHandler extends ChannelInboundHandlerAdapter {

    private Integer value;

    public ServerHandler(Integer value) {
        this.value = value;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        String s = (String) msg;

        try {

            Integer i = Integer.parseInt(s.substring(0, s.length() - 1));
            this.value += i;
            System.out.println("Value its now: " + this.value);

        } catch (NumberFormatException n) {
            System.out.println("Not a number received");
        }

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.err.println(cause.getMessage());
        ctx.close();
    }
}

单独来说,它是工作的,当一个客户机通过nc输入一个它递增但不是全局递增的数字时,我的意思是当一个不同的客户机启动时,计数器设置为0。

您的变量没有正确的同步;它通常应该声明为volatile,以确保所有线程都看到更新的值,并且您需要同步使用它的块。但是,在您的情况下,使用原子整数将更简单、更有效。

您的变量没有正确的同步;它通常应该声明为volatile,以确保所有线程都看到更新的值,并且您需要同步使用它的块。但是,在您的情况下,使用原子整数将更简单、更有效。

您的变量没有正确的同步;它通常应该声明为volatile,以确保所有线程都看到更新的值,并且您需要同步使用它的块。但是,在您的情况下,使用原子整数将更简单、更有效。

您的变量没有正确的同步;它通常应该声明为volatile,以确保所有线程都看到更新的值,并且您需要同步使用它的块。但是,在您的情况下,使用原子整数将更简单、更有效。

谢谢!我不知道原子整数。但由于这是一个学术练习,我解决了这个问题,在我自己的类中封装了一个int,它可以工作,我只在使用int或Integer时遇到这个问题。简单地问一下,这个解决方案会出现concurreny问题还是需要同步增量方法?是的,Java整数是不可变的对象,共享它没有意义。@JoséRicardoRibeiro经典的读取(threadA)-读取(threadB)-更新(threadA)-更新仍然会有问题(threadB,但丢失threadA的更新)场景。这正是AtomicInteger#addAndGet()的内容避免。请注意,
AtomicInteger
是自Java 5以来核心Java库的一部分,因此请确保您不能继续使用它。谢谢!我不知道AtomicInteger。但由于这是一个学术练习,我在自己的类中封装了一个int解决了这个问题,并且它可以工作,我只在使用int或Inte时才会遇到这个问题问一个简单的问题,这个解决方案会出现concurreny问题还是需要同步增量方法?对,Java整数是不可变的对象,共享它没有意义。@JoséRicardoRibeiro经典的read(threadA)-read(threadB)-update(threadA)-update仍然会有问题(threadB,但丢失threadA的更新)场景。这正是AtomicInteger#addAndGet()的内容避免。请注意,
AtomicInteger
是自Java 5以来核心Java库的一部分,因此请确保您不能继续使用它。谢谢!我不知道AtomicInteger。但由于这是一个学术练习,我在自己的类中封装了一个int解决了这个问题,并且它可以工作,我只在使用int或Inte时才会遇到这个问题问一个简单的问题,这个解决方案会出现concurreny问题还是需要同步增量方法?对,Java整数是不可变的对象,共享它没有意义。@JoséRicardoRibeiro经典的read(threadA)-read(threadB)-update(threadA)-update仍然会有问题(threadB,但丢失threadA的更新)场景。这正是AtomicInteger#addAndGet()的内容避免。请注意,
AtomicInteger
是自Java 5以来核心Java库的一部分,因此请确保您不能继续使用它。谢谢!我不知道AtomicInteger。但由于这是一个学术练习,我在自己的类中封装了一个int解决了这个问题,并且它可以工作,我只在使用int或Inte时才会遇到这个问题问一个简单的问题,这个解决方案会出现concurreny问题还是需要同步增量方法?对,Java整数是不可变的对象,共享它没有意义。@JoséRicardoRibeiro经典的read(threadA)-read(threadB)-update(threadA)-update仍然会有问题(threadB,但丢失threadA的更新)场景。这正是
AtomicInteger#addAndGet()
避免的。需要注意的是,
AtomicInteger
是自Java 5以来核心Java库的一部分,因此请确保您不能继续使用它。