一、进程&线程

进程:正在执行的程序,每个进程都是由程序代码组成;

线程:代码在进程中执行的流程;

比如:打开的迅雷就是一个进程,下载的任务就是线程,所以一个进程可以有多个线程。

线程实现方式:

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();
}

}

}

}