一、线程创建
1.1 继承方式
- 创建类,通过继承Thread,重写父类的run()。
- 使用创建对象,调用start()方法,程序会单开线程,再自动调用run()方法。
1.2 实现接口方式
- 创建类,实现Runnable接口
- 创建对象,创建Thread对象,并传入创建的对象,Thread对象调用start()方法。
PS:
private void fun(){
//直接建
new Thread(){
@Override
public void run() {
super.run();
}
}.start();
//runnable
new Thread(new Runnable() {
@Override
public void run() {
}
}).start();
}
二、线程使用
- setName函数,设置线程的名称
其他默认名字,main线程 - Thread.currentThread.getname() 显示当前线程的名称
2.1 线程异常问题
2.2 线程睡眠
- sleep方法, 参数是毫秒,必须处理异常
- 在此线程睡眠时,不参与CPU的竞争,睡眠结束后,重新加入到CPU的竞争。
2.3 线程让步
- 当线程执行到此处时,此线程暂时在此处停止,让出竞争到CPU,当下次竞争到CPU时,接着此处继续执行。
2.4 线程阻塞
- 遇到join阻塞语句时,暂停当前线程,直至调用join的线程执行完毕,其他线程才开始继续竞争CPU,执行程序。
三、线程优先级
- 优先级不是绝对的,优先级高,只是在竞争CPU时候,分到的几率比较高。
- 线程默认级别是5,数字越大,优先级越高。
线程安全问题
package me.gacl.util;
import me.gacl.util.UDPServer;
import me.gacl.domain.ClientInfo;
//采用饿汉式单例类,类初始化时,已经自行实例化,线程安全好
public class SocketUtil {
private SocketUtil(){};
private static final SocketUtil socketUtil = new SocketUtil();
//静态工厂方法
public static SocketUtil getInstance() {
return socketUtil;
}
static{
//启动socket 服务器类
UDPServer sharedUDPServer = UDPServer.getInstance();
Thread serverThread = new Thread(sharedUDPServer);
serverThread.start();
}
//添加要转发的客户端信息,线程安全问题
public synchronized void addClientInfoToSocketList(String userName, ClientInfo clientInfo){
UDPServer sharedUDPServer = UDPServer.getInstance();
sharedUDPServer.clientInfoList.put(userName, clientInfo);
}
}
package me.gacl.util;
//import java.awt.RenderingHints.Key;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Iterator;
import me.gacl.domain.ClientInfo;
import me.gacl.util.UDPSend;
//import org.apache.tomcat.util.security.PrivilegedSetTccl;
public class UDPServer implements Runnable{
//单例
private UDPServer(){}
private static UDPServer sharedUdpServer = new UDPServer();
public static UDPServer getInstance(){
return sharedUdpServer;
}
//客户端数据
public HashMap<String, ClientInfo> clientInfoList = new HashMap<String, ClientInfo>();
//线程
private static final int INPORT = 5000;
private DatagramSocket serverSocket;
private byte[] recvBuf = new byte[1024];
private DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
@Override
public void run(){
//创建udp服务器
try {
serverSocket = new DatagramSocket(INPORT);
System.out.println("Server started !");
while (true){
serverSocket.receive(packet);
synchronized (this) {
String recString = new String(packet.getData(), 0, packet.getLength());
//打印接收的信息
String rcvd = "address:"
+ packet.getAddress() + ",port:" + packet.getPort()+",message:"+recString;
System.out.println("From Client:"+rcvd);
//打印clientInfoList
if (recString.equals("761399882")) {
//测试list
Iterator<String> iterator = clientInfoList.keySet().iterator();
while (iterator.hasNext()) {
String string = (String) iterator.next();
ClientInfo clientInfo = clientInfoList.get(string);
System.out.println("key:"+string+"\t"+"value: "+clientInfo.getIpString()+"\t"+clientInfo.getPortInt());
}
continue;
}
//处理接受的数据
if (clientInfoList.containsKey(recString)) {
ClientInfo clientInfo = clientInfoList.get(recString);
UDPSend udpSend = new UDPSend(recString, clientInfo, serverSocket);
udpSend.start();
}
}
//对接收到的数据处理转发
//测试list
/* Iterator<String> iterator = clientInfoList.keySet().iterator();
while (iterator.hasNext()) {
String string = (String) iterator.next();
ClientInfo clientInfo = clientInfoList.get(string);
System.out.println("key:"+string+"\t"+"value: "+clientInfo.getIpString()+"\t"+clientInfo.getPortInt());
}*/
}
} catch (SocketException e) {
System.err.println("Can't open socket");
//System.exit(1);
} catch (Exception e) {
System.err.println("Communication error");
e.printStackTrace();
} finally{
serverSocket.close();
}
}
}
package me.gacl.util;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import me.gacl.domain.ClientInfo;
public class UDPSend extends Thread{
private String sendStr;
private ClientInfo clientInfo;
private DatagramSocket serverSocket;
public UDPSend(String sendStr, ClientInfo clientInfo,
DatagramSocket serverSocket) {
super();
this.sendStr = sendStr;
this.clientInfo = clientInfo;
this.serverSocket = serverSocket;
}
public void run() {
synchronized (this) {
System.out.println("UDPSend:"+clientInfo.getIpString()+"\t"+clientInfo.getPortInt());
try {
InetAddress address = InetAddress.getByName(clientInfo.getIpString());
int port = clientInfo.getPortInt();
byte[] sendBuf = sendStr.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendBuf, sendBuf.length, address, port);
serverSocket.send(sendPacket);
//线程安全测试
//sleep(9000);
//System.out.println("serverSocket.send"+sendStr);
} catch (Exception e) {
System.err.println("Communication error");
e.printStackTrace();
}
}
}
}