一、进程&线程
进程:正在执行的程序,每个进程都是由程序代码组成;
线程:代码在进程中执行的流程;
比如:打开的迅雷就是一个进程,下载的任务就是线程,所以一个进程可以有多个线程。
线程实现方式:
1、继承Thread类
在类中重写run方法,run方法里是要执行的任务,然后创建对象,通过对象调用start方法。
2、实现Runnable接口
在类中重写run方法,创建Thread对象,将接口的实现类作为参数传给Thread类,然后调用Thread类的start方法
总结:只有调用Thread类的start方法才能开启一个线程,thread的run方法只是一个普通方法。
二、Synchronized&Lock
synchronized: 代码块被synchronized修饰后,其他线程便只能一直等待,只有当该代码块执行结束或者出现异常,才会释放锁。
lock: 不让等待的线程一直无期限地等待下去,使用lock。
总结:Lock是一个接口,而synchronized是Java中的关键字;
synchronized在发生异常时,会自动释放线程占有的锁,使用Lock时需要在finally块中释放锁;
在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。
三、线程池
如果程序中有大量线程任务,将会花费大量时间创建和销毁线程,系统效率很低,而线程池里的每一个线程任务结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用,因而借助线程池可以提高程序的执行效率。
线程池类型:
• FixedThreadPool:固定线程数线程池,提交任务时创建线程,直到池的最大容量,如果有线程非预期结束,会补充新线程
• CachedThreadPool:可变线程池,它犹如一个弹簧,如果没有任务需求时,它回收空闲线程,如果需求增加,则按需增加线程,不对池的大小做限制
• SingleThreadExecutor:单一线程。处理不过来的任务会进入FIFO队列等待执行
• SecheduledThreadPool:周期性线程池。支持执行周期性线程任务
fixedPool提交线程,runnable无返回值,callable有返回值,但主线程被阻塞的时候,需要等待任务线程返回才能拿到结果;
schedulerPool调用submit,提交任务时,跟普通pool效果一致;调用schedule提交任务时,则可按延迟,按间隔时长来调度线程的运行。
四、socket
1、socket服务端
public class ServiceServer {
public static void main(String[] args) throws Exception {
// 创建一个serversocket,绑定到本机的8899端口上
ServerSocket server = new ServerSocket();
server.bind(new InetSocketAddress("localhost", 8899));
// 接受客户端的连接请求;accept是一个阻塞方法,会一直等待,到有客户端请求连接才返回
while (true) {
Socket socket = server.accept();
new Thread(new ServiceServerTask(socket)).start();
}
}
}
2、socket客户端
public class ServiceClient {
public static void main(String[] args) throws Exception {
/*ServiceIterface service = ProxyUtils.getProxy(ServiceIterface.class,"methodA",hostname,port);
Result = service.methodA(parameters);*/
// 向服务器发出请求建立连接
Socket socket = new Socket("localhost", 8899);
// 从socket中获取输入输出流
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
PrintWriter pw = new PrintWriter(outputStream);
pw.println("hello");
pw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
String result = br.readLine();
System.out.println(result);
inputStream.close();
outputStream.close();
socket.close();
}
}
3、业务方法
public class GetDataServiceImpl {
public String getData(String param){
return "ok-"+param;
}
}
4、线程实体类
public class ServiceServerTask implements Runnable{
Socket socket ;
InputStream in=null;
OutputStream out = null;
public ServiceServerTask(Socket socket) {
this.socket = socket;
}
//业务逻辑:跟客户端进行数据交互
@Override
public void run() {
try {
//从socket连接中获取到与client之间的网络通信输入输出流
in = socket.getInputStream();
out = socket.getOutputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
//从网络通信输入流中读取客户端发送过来的数据
//注意:socketinputstream的读数据的方法都是阻塞的
String param = br.readLine();
GetDataServiceImpl getDataServiceImpl = new GetDataServiceImpl();
String result = getDataServiceImpl.getData(param);
//将调用结果写到sokect的输出流中,以发送给客户端
PrintWriter pw = new PrintWriter(out);
pw.println(result);
pw.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
in.close();
out.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}