关于java多线程说明;
start()方法的调用后并不是立即执行多线程代码,而是使得该线程变为可运行态,什么时候运行是由操作系统决定的。针对Thread类,从程序1运行的结果可以发现,多线程程序是乱序执行(即先执行完线程a全部操作再进行线程B操作)。因此,只有乱序执行的代码才有必要设计为多线程。假如我们对线程进行sleep操作,我们可以发现线程Asleep时线程B会进行操作,因此Thread.sleep()方法调用目的是不让当前线程独自霸占该进程所获取的CPU资源,以留出一定时间给其他线程执行的机会。了解这一点,我们可以进行以下实验
1,编写一个类,类名为SubThread,继承Thread。该类中:
代码如下:
package network_chap05;
public class SubThread extends Thread {
public String threadName;
public static void main(String[] args) {
// TODO Auto-generated method stub
new SubThread("First").start();
new SubThread("Second").start();
new SubThread("Third").start();
}
public SubThread_Test(String threadName){
this.threadName = threadName;
}
public void run() {
for(int i=1;i<=5;i++){
System.out.print("A线程循环了第"+i+"次\n");
try {
sleep(new java.util.Random().nextInt(1000) + 1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.print("A线程"+"finished\n");
}
}
Synchronized实现同步运算
分析:
在 Java 中,关键字 synchronized可以保证在同一个时刻,只有一个线程可以执行某个方法或者某个代码块。
同一进程的多个线程共享同一片存储空间,为了避免访问冲突的情况,JAVA提供了一种同步机制的办法,用synchronized关键字来修饰共享的代码块,确保在某个时刻只有一个线程允许执行特定的代码块。
当一个线程在访问被synchronized修饰的数据时,会将其“上锁”,阻止其他线程访问。只有当前线程访问完这部分数据后释放锁标志,其他线程才可以访问。
注意:无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或方法当作锁。
synchronized关键字最主要有以下3种应用方式,
修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁
修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁
修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁
举例如下:
未使用Synchronized时:
class MySyncThreadApp
package network_chap05;
public class MySyncThreadApp {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
MyCalculate cal = new MyCalculate();
MySyncThread a = new MySyncThread("A",cal);
MySyncThread b = new MySyncThread("B",cal);
MySyncThread c = new MySyncThread("C",cal);
MySyncThread d = new MySyncThread("D",cal);
a.start();
b.start();
c.start();
d.start();
}
}
class MyCalculate
package network_chap05;
public class MyCalculate {
private int count =0;
public synchronized void setCount(){
count++;
}
public int getCount(){
return count;
}
}
class MySyncThread
package network_chap05;
public class MySyncThread extends Thread {
public MyCalculate cal;
public String name;
public MySyncThread (String name, MyCalculate cal) {
super(name);
this.cal = cal;
}
public void run (){
for(int i=0;i<100000;i++){
cal.setCount();
}
System.out.println(getName() + " end, the count is: " + cal.getCount());
}
}
通过运行我们发现:
很明显,我们发现,我们开启4个线程,每个线程都调用同一个函数cal进行计数,但最后一个结束的线程输出结果却没有达到40000,原因便是:如下图,当第一个线程运行cal到5,此时运行第6次,但是当运行到第一句代码时,第一个线程的时间片用完了,此时cal=5,这时候时间片轮到第二个线程,假如第二个线程用完时间片时把把代码全部运行完,假设此时从cal=5到了600,此时时间片假如又轮到第一个线程,而此时第一个线程运行第二句代码,因此cal依旧还是5,加1后cal=6,输出cal后,cal从600变成了6,所以这样导致我们达不到多线程的效果,而Synchronized就是将程序进行“上锁”,回到刚刚的情况,当运行到第一句代码时,第一个线程的时间片用完了,此时cal=5,由于使用Synchronized导致程序“上锁”,因为后面3个线程拿不到时间片,进入堵塞状态,只有当再次轮到第一个线程拿到时间片进行运行时,才能“解锁”。
实现如下:
修改class MyCalculate
package network_chap05;
public class MyCalculate {
private int count =0;
public synchronized void setCount(){
count++;
}
public int getCount(){
return count;
}
}
运行结果如下:
将前面的MyServer,MyClient,ClientThread改写为多线程格式
实现思路:
MyClient:
1,原先的MyServer,使用线程ClientThread进行接收,没有发的线程,为了使服务器能只有与客户机进行交互,因此需要再建立一个线程,用于返回抓取text框内需要返回给客户机的信息。
2,该线程再抓取完信息之后启动。
MyClient:
将Client进行信息收发的步骤改写为两个线程,一个线程进行发,一个线程进行收。
实现代码如下:
class ClientThread
package cn.edu.sise;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JTextArea;
/**
*
* @author World
*/
public class ClientThread extends Thread {
private Socket toClientSocket=null;//会话套接字
private BufferedReader in; //网络输入流
private PrintWriter out; //网络输出流
private int clientCounts=0;//在线客户机总数
// public ClientThread(Socket toClientSocket,int clientCounts) { //构造函数
// this.toClientSocket=toClientSocket;
// this.clientCounts=clientCounts;
// }
private JTextArea jta;
public ClientThread(Socket toClientSocket,int clientCounts, JTextArea jta) { //构造函数
this.toClientSocket=toClientSocket;
this.clientCounts=clientCounts;
this.jta = jta;
}
@Override
public void run(){
try {
// 创建绑定到套接字toClientSocket上的网络输入流与输出流
in=new BufferedReader(new InputStreamReader(toClientSocket.getInputStream(),"UTF-8"));
out=new PrintWriter(new OutputStreamWriter(toClientSocket.getOutputStream(),"UTF-8"),true);
//5. 根据服务器协议,在网络流上进行读写操作
String recvStr;
while ((recvStr=in.readLine())!=null){ //只要客户机不关闭,则反复等待和接收客户机消息
Date date=new Date();
DateFormat format=new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
String time=format.format(date);
jta.append(toClientSocket.getRemoteSocketAddress()+ " 客户机编号: "+clientCounts+" 消息:"+recvStr+" :"+time+"\n"); //解析并显示收到的消息
//按照echo协议原封不动回送消息
out.println(toClientSocket.getLocalSocketAddress()+ " 客户机编号: "+clientCounts+" Echo消息:"+recvStr+" : "+time);
}//end while
MyServer.clientCounts--; //客户机总数减1
}catch (IOException ex) {}finally{
try {
//远程客户机断开连接,线程释放资源
if (in!=null) in.close();
if (out!=null) out.close();
if (toClientSocket!=null) toClientSocket.close();
} catch (Exception e) {
// TODO: handle exception
}
}
} //end run
} //end class
class MyClient
package cn.edu.sise;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.ScrollPane;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class MyClient {
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame frame = new JFrame("Client: 1707");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new MyPanel());
frame.setPreferredSize(new Dimension(800, 300));
frame.pack();
frame.setVisible(true);
}
}
class MyPanel extends JPanel{
JTextField tf;
JTextArea ta;
JTextField tfAddr;
JTextField tfPort;
BufferedReader in = null;
BufferedWriter out = null;
public MyPanel(){
this.setLayout(new BorderLayout());
JPanel pcon = new JPanel();
JLabel lb1 = new JLabel();
lb1.setFont(new java.awt.Font("宋体", 1, 16)); // NOI18N
lb1.setText("Server Host Name:");
tfAddr = new JTextField(25);
JLabel lb2 = new JLabel();
lb2.setFont(new java.awt.Font("宋体", 1, 16)); // NOI18N
lb2.setText("Port:");
tfPort = new JTextField(5);
JButton btnConnect = new JButton("Connect");
btnConnect.addActionListener(new MyConnectListerner());
pcon.add(lb1);
pcon.add(tfAddr);
pcon.add(lb2);
pcon.add(tfPort);
pcon.add(btnConnect);
pcon.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Connection Border",
javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
javax.swing.border.TitledBorder.DEFAULT_POSITION,
new java.awt.Font("宋体", 1, 14))); // NOI18N
this.add(pcon, BorderLayout.NORTH);
JPanel pcom = new JPanel();
JLabel lb3 = new JLabel();
lb3.setFont(new java.awt.Font("宋体", 1, 16)); // NOI18N
lb3.setText("Message:");
pcom.add(lb3);
tf = new JTextField(25);
pcom.add(tf );
JButton btn = new JButton("Send");
btn.addActionListener(new MySendListerner());
pcom.add(btn);
pcom.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Communication Border",
javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
javax.swing.border.TitledBorder.DEFAULT_POSITION,
new java.awt.Font("宋体", 1, 14))); // NOI18N
this.add(pcom, BorderLayout.SOUTH);
JPanel pinfo = new JPanel();
pinfo.setLayout(new java.awt.BorderLayout());
pinfo.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Information Border",
javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
javax.swing.border.TitledBorder.DEFAULT_POSITION,
new java.awt.Font("宋体", 1, 14))); // NOI18N
JScrollPane sp1 = new JScrollPane();
sp1.setPreferredSize(new java.awt.Dimension(8, 250));
ta = new JTextArea(5, 10);
ta.setEditable(false);
sp1.setViewportView(ta);
pinfo.add(sp1, BorderLayout.CENTER);
this.add(pinfo, BorderLayout.CENTER);
}
class MyConnectListerner implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
String addr = tfAddr.getText();
if(addr.trim().equals("")) addr = "localhost";
int port = Integer.parseInt(tfPort.getText());
System.out.println(addr + ":" + port);
try{
Socket s = new Socket();
SocketAddress remoteAddr=new InetSocketAddress(addr,port);
s.connect(remoteAddr);
ta.append("Connect to server: " + addr + ":" + port + "\n");
in = new BufferedReader(
new InputStreamReader(s.getInputStream(),"UTF-8"));
out = new BufferedWriter(
new OutputStreamWriter(s.getOutputStream(),"UTF-8"));
new Thread(new MessageReceiver()).start();
} catch (IOException ex) {
System.out.println("异常信息:"+ex.getMessage());
}
}
}
class MySendListerner implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
new Thread(new MessageSender()).start();
}
}
class MessageSender implements Runnable{
@Override
public void run() {
try {
String sendStr = tf.getText();
tf.setText("");
out.write(sendStr); //向服务器发送字符串
out.newLine();
out.flush();
System.out.println("3.1向服务器发送字符串成功!" + sendStr);
ta.append("To server: " + sendStr + "\n");
} catch (IOException ex) {
System.out.println("异常信息:" + ex.getMessage());
}
}
}
class MessageReceiver implements Runnable{
@Override
public void run() {
String receiver;
try {
while ((receiver = in.readLine())!=null){
ta.append("From Server: " + receiver + "\n");
}
} catch (IOException ex) {
System.out.println("异常信息:" + ex.getMessage());
}
}
}
}
class MyServer
package cn.edu.sise;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import cn.edu.sise.MyPanel.MySendListerner;
/**
* Echo服务器:根据Echo协议,接收来自客户机消息,并立即回送。
*/
public class MyServer extends javax.swing.JFrame {
private ServerSocket listenSocket=null; //侦听套接字
private Socket toClientSocket=null; //与客户机对话的套接字
public static int clientCounts=0; //客户数量编号
/**
* Creates new form EchoServer
*/
public MyServer() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// //GEN-BEGIN:initComponents
private void initComponents() {
topPanel = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
txtHostName = new javax.swing.JTextField();
jLabel2 = new javax.swing.JLabel();
txtHostPort = new javax.swing.JTextField();
btnStart = new javax.swing.JButton();
midPanel = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
txtArea = new javax.swing.JTextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("My Server: 1707");
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
formWindowClosing(evt);
}
});
topPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Server Info Border", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("宋体", 1, 18))); // NOI18N
jLabel1.setFont(new java.awt.Font("宋体", 1, 16)); // NOI18N
jLabel1.setText("Host Name:");
txtHostName.setFont(new java.awt.Font("宋体", 1, 16)); // NOI18N
txtHostName.setText("localhost");
jLabel2.setFont(new java.awt.Font("宋体", 1, 16)); // NOI18N
jLabel2.setText("Port:");
txtHostPort.setFont(new java.awt.Font("宋体", 1, 16)); // NOI18N
txtHostPort.setText("7");
btnStart.setFont(new java.awt.Font("宋体", 1, 16)); // NOI18N
btnStart.setText("Start");
btnStart.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnStartActionPerformed(evt);
}
});
javax.swing.GroupLayout topPanelLayout = new javax.swing.GroupLayout(topPanel);
topPanel.setLayout(topPanelLayout);
topPanelLayout.setHorizontalGroup(
topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(topPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(txtHostName, javax.swing.GroupLayout.DEFAULT_SIZE, 131, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(txtHostPort, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(btnStart)
.addContainerGap())
);
topPanelLayout.setVerticalGroup(
topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(topPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(txtHostName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel2)
.addComponent(txtHostPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnStart))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
getContentPane().add(topPanel, java.awt.BorderLayout.PAGE_START);
midPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Information Border", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("宋体", 1, 18))); // NOI18N
midPanel.setLayout(new java.awt.BorderLayout());
txtArea.setEditable(false);
txtArea.setBackground(new java.awt.Color(204, 255, 255));
txtArea.setColumns(20);
txtArea.setFont(new java.awt.Font("宋体", 1, 16)); // NOI18N
txtArea.setRows(5);
jScrollPane1.setViewportView(txtArea);
midPanel.add(jScrollPane1, java.awt.BorderLayout.CENTER);
getContentPane().add(midPanel, java.awt.BorderLayout.CENTER);
pack();
}// //GEN-END:initComponents
//启动服务器
private void btnStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnStartActionPerformed
try {
btnStart.setEnabled(false); //禁用按钮,避免重复启动
String hostName=txtHostName.getText();//主机名
int hostPort=Integer.parseInt(txtHostPort.getText());//端口
//构建服务器的SocketAddress格式地址
SocketAddress serverAddr=new InetSocketAddress(InetAddress.getByName(hostName),hostPort);
listenSocket=new ServerSocket(); //创建侦听套接字
listenSocket.bind(serverAddr); //绑定到工作地址
txtArea.append("服务器开始等待客户机连接...\n");
} catch (IOException ex) { }
//创建一个匿名线程,用于侦听和接受客户机连接,并创建响应客户机的会话线程
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) { //处理客户机连接
toClientSocket=listenSocket.accept();//侦听并接受客户机连接
clientCounts++;//客户机数量加1
txtArea.append(toClientSocket.getRemoteSocketAddress()+ " 客户机编号: "+clientCounts+ " 会话开始...\n");
JFrame frame = new JFrame("From Client: "+ toClientSocket.getRemoteSocketAddress());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel panel = new MyPanel();
frame.getContentPane().add(panel);
frame.setPreferredSize(new Dimension(600, 300));
frame.pack();
frame.setVisible(true);
//创建客户线程clientThread,实现一客户一线程
Thread clientThread=new ClientThread(toClientSocket,clientCounts,panel.taClient);
clientThread.start(); //启动任务线程
} //end while
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, ex.getMessage(), "错误提示", JOptionPane.ERROR_MESSAGE);
}
}//end run()
class MyPanel extends JPanel{
public javax.swing.JTextArea taClient;
JTextField tf;
public MyPanel(){
this.setLayout(new BorderLayout());
JPanel pinfo = new JPanel();
JPanel border = new JPanel();
pinfo.setLayout(new java.awt.BorderLayout());
pinfo.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Information Border",
javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
javax.swing.border.TitledBorder.DEFAULT_POSITION,
new java.awt.Font("宋体", 1, 14))); // NOI18N
JScrollPane sp1 = new JScrollPane();
sp1.setPreferredSize(new java.awt.Dimension(8, 250));
taClient = new JTextArea(5,10);
taClient.setEditable(false);
sp1.setViewportView(taClient);
pinfo.add(sp1,BorderLayout.CENTER);
this.add(pinfo, BorderLayout.CENTER);
tf=new JTextField(40);
JButton tfbtn_send = new JButton("Send");
tfbtn_send.addActionListener(new MySendListerner());
border.add(tfbtn_send);
border.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Communication Border",
javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
javax.swing.border.TitledBorder.DEFAULT_POSITION,
new java.awt.Font("宋体", 1, 14))); // NOI18N
border.add(tf);
border.add(tfbtn_send);
this.add(border, BorderLayout.SOUTH);
new Thread(new MessageRecver()).start();
}
class MySendListerner implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
new Thread(new Runnable() {
@Override
public void run() {
try {
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(toClientSocket.getOutputStream()));
out.write(tf.getText());
out.newLine();
out.flush();
taClient.append("To client: " + tf.getText());
tf.setText("");
} catch (IOException e1) {
e1.printStackTrace();
}
}
}).start();
}
}
class MessageRecver implements Runnable{
@Override
public void run() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(toClientSocket.getInputStream()));
String recvMessage;
while ((recvMessage = in.readLine())!=null){
taClient.append("From client: " + recvMessage + "\n");
}
} catch (IOException e) {
e.printStackTrace();
};
}
}
}
}).start();
}//GEN-LAST:event_btnStartActionPerformed
//关闭服务器之前
private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
//关闭服务器之前释放套接字
if (listenSocket!=null) listenSocket=null;
if (toClientSocket!=null) toClientSocket=null;
}//GEN-LAST:event_formWindowClosing
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(MyServer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(MyServer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(MyServer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(MyServer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//
//
//
//
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MyServer().setVisible(true);
}
});
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnStart;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JPanel midPanel;
private javax.swing.JPanel topPanel;
public static javax.swing.JTextArea txtArea;
private javax.swing.JTextField txtHostName;
private javax.swing.JTextField txtHostPort;
// End of variables declaration//GEN-END:variables
}