读书人

网络编程 多线程 时钟,该怎么处理

发布时间: 2012-02-19 19:43:38 作者: rapoo

网络编程 多线程 时钟
我的服务端对应很多用户,与每一个用户交互都是用的一个线程。用户的功能可以告诉服务端 “是”或者“否”

我想在特定场景触发时,服务端让其他用户的功能都disable掉,然后只是enable一个用户的功能,并且只给这个用户30秒时间回答“是/否”,客户回答后,disable这个客户。如果用户超时,没有回答,视为回答否,仍然disable这个客户。

我比较迷茫的是,30秒这个怎么做,多线程下有什么好的时钟之类的东西,可以不影响别的线程么,因为有时候是同时enable多个用户,让他们都作答“是否”,什么时钟是只影响当前这一个线程,而且在被通知用户的答案后会自动结束计时的呢。

谢谢了!

[解决办法]
你自己为用户创建“计时器“不行吗?时间达到要求后执行其他操作

类似下面的写法:

Assembly code
import java.awt.*;import java.awt.event.*;import java.text.SimpleDateFormat;import java.util.*;import javax.swing.*;import javax.swing.border.*;public class TestTimePieceJFrame extends JFrame {    ControlPanel controlPane = null; //-----------------控制面板    JTextField jTextField;    public TestTimePieceJFrame() {    super();    init();    }    private void init() {    controlPane = new ControlPanel(this);    add(controlPane);    setPreferredSize(new Dimension(300, 170));    pack();    setVisible(true);    setResizable(false);    this.setLocationRelativeTo(null);    this.setDefaultCloseOperation(EXIT_ON_CLOSE);    addKeyListener(new TimePieceKeyListener());    }    public static void main(String[] args) {    new TestTimePieceJFrame();    ;    }    class TimePieceKeyListener extends KeyAdapter {    public void keyReleased(KeyEvent e) {        controlPane.keyReleased(e);    }    }}class ControlPanel extends JPanel {    private JFrame snakeFrame = null;    JLabel jLabel,jLabel1, jLabel2, jLabel3, jLabel4;    Date dateWhenStartJpanel;//保存程序启动时的时间        Date dateWhenClickF5;    Thread thread ;    public ControlPanel(JFrame snakeFrame) {    super();    this.snakeFrame = snakeFrame;    init();    }    private void init() {    dateWhenStartJpanel = new Date();    setSize(608, 31);    setBackground(Color.WHITE);    setLayout(new FlowLayout());    setBorder(new LineBorder(Color.white, 5));    setLayout(new FlowLayout());    jLabel = new JLabel();    jLabel1 = new JLabel();    jLabel2 = new JLabel();    jLabel3 = new JLabel();    jLabel4 = new JLabel();    add(jLabel);    add(jLabel1);    add(jLabel2);    add(jLabel3);    add(jLabel4);    jLabel.setText("F5:开始计时 F6:停止计时");    }      public void keyReleased(KeyEvent e) {    int keyCode = e.getKeyCode();    if (keyCode == KeyEvent.VK_F5) {        dateWhenClickF5 = new Date();//sava time when click F5        thread = new Thread(new TimePieceRunnable())        ;thread.start();    } else if (keyCode == KeyEvent.VK_F6) {        if(thread != null)thread.stop();        else prompt("请先按F5");    }    }    class TimePieceRunnable implements Runnable {    public void run() {        while (true) {        Date tempDate = new Date();        String tempString = formateToTime(tempDate, "现在时间是 E kk:mm:ss:");        jLabel1.setText(tempString);        tempString = formateToTime(dateWhenStartJpanel,            "启动程序时间是 E kk:mm:ss:");        jLabel2.setText(tempString);                tempString = formateToTime(dateWhenClickF5,            "最近一次按动F5时间是 E kk:mm:ss:");        jLabel3.setText(tempString);        tempDate = getMillisOfTimeDifference(dateWhenClickF5, tempDate);                tempString = formateToTime(tempDate,            "最近一次按动F5到现在的时间差是 kk:mm:ss:");        jLabel4.setText(tempString);        try {                       repaint();            Thread.sleep(100);////每隔0.1秒刷新一次        } catch (InterruptedException e) {                     e.printStackTrace();        }        }    }    }    public String formateToTime(Date date, String timeRegex) {    //Date date = new Date();    //SimpleDateFormat f = new SimpleDateFormat("'BeiJing Time':yyyy年MM月dd日 E kk时mm分ss秒");    SimpleDateFormat f = new SimpleDateFormat(timeRegex);    String newTypeDate = f.format(date);    return newTypeDate;    }    public Date getMillisOfTimeDifference(Date date1, Date date2) {    Calendar calendar = Calendar.getInstance();    calendar.setTime(date1);    long timelnMillis1 = calendar.getTimeInMillis();    calendar.setTime(date2);    long timelnMillis2 = calendar.getTimeInMillis();    calendar.setTimeInMillis(timelnMillis2 - timelnMillis1);    return calendar.getTime();    }         private static int prompt(String promptMessage) {    return JOptionPane.showConfirmDialog(null, promptMessage, "友情提示",        JOptionPane.WARNING_MESSAGE);    }  } 


[解决办法]
这里我觉得应该这样设置。
有一个专门的线程来做时钟运转。
至于用户启用与否,这个由每个用户单独的线程去扫描。
而不要由程序统一来做,在一个大并发量你统一描述根本不行。
[解决办法]
有一个专门的Timer类啊,直接通过这个来实现就可以了啊
建议看看API,用法很简单的,和普通线程操作都差不多
[解决办法]
一个用户使用一个 java.util.concurrent.Future。 Future的 get(30,TimeUnit.SECONDS)
[解决办法]
其实也可以用socket.setSoTimeout(30000)这个方法来实现,如果socket在30秒内没有读到任何信息,就会抛出一个SocketTimeoutException,然后你捕获这个异常关闭socket就行了

Java code
import java.io.*;import java.net.*;public class Server {    private ServerSocket server;        public Server() throws Exception    {        server = new ServerSocket(9999);        while (true)        {            Socket socket = server.accept();            new ListenThread(socket).start();        }    }        public static void main(String[] args) throws Exception    {        new Server();    }        private class ListenThread extends Thread    {        private Socket socket;                public ListenThread(Socket socket)        {            this.socket = socket;        }                public void run()        {            try            {                try                {                    socket.setSoTimeout(30000);    //设置socket超时时间为30秒                    System.out.println("accept " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort());                    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));                    PrintWriter out = new PrintWriter(socket.getOutputStream());                                        out.println("请选择(y/n)");                    out.flush();                    String str = in.readLine();                    if (str.equalsIgnoreCase("y"))    //用户选是,启动回显功能                    {                        socket.setSoTimeout(0);    //不限制超时时间                        System.out.println(socket.getInetAddress().getHostAddress() + ":" + socket.getPort() + "选择y");                        while ((str = in.readLine()) != null)                        {                            out.println(str);                            out.flush();                        }                    }                    else                    {                        System.out.println(socket.getInetAddress().getHostAddress() + ":" + socket.getPort() + "选择n");                    }                }                finally                {                    System.out.println(socket.getInetAddress().getHostAddress() + ":" + socket.getPort() + "关闭");                    socket.close();                }            }            catch (SocketTimeoutException e)    //捕获到超时异常            {                System.out.println(socket.getInetAddress().getHostAddress() + ":" + socket.getPort() + "超时");                try                 {                    socket.close();                }                catch (IOException e1)                 {}            }            catch (Exception e)            {}        }    }} 

读书人网 >J2SE开发

热点推荐