8.多线程和Socket通信
一、多线程
1、进程的概念:
进程就是应用程序的执行实例,有独立的内存空间和系统资源。当一个应用程序没有执行的时候,它就不是一个进程。
2、进行的特征:
(1)动态性:动态产生动态消亡。
(2)并发性:多个应用程序同时在运行。
(3)独立性:独立运行。
3、线程的概念:
线程是进行内部的一个执行单元,它是程序中一个单一的顺序控制流程。
4、线程的特点:
(1)一个进程可以包含多个线程,而一个线程至少要有一个父进程。
注意:一个线程是不能离开进程独立存在的
(2)线程可以有自己的堆栈,程序计数器和局部变量。
(3)线程与父进程的其他线程共享进程中所有的资源。
(4)独立运行,采用独占方式。
(5)一个线程可以创建和删除另外一个线程。
(6)同一个进程中的多个线程之间可以并发执行。
(7)线程的调度管理是由进行来完成的
5、每个程序至少自动拥有一个线程,称为主线程。当程序加载到内存中,启动主线程。
6、Java中的public static void main()方法是主线程的入口。
7、使用线程的四个步骤:
(1)定义线程,并执行该线程完成的功能。
(2)创建线程对象
(3)启动线程
(4)终止线程
8、创建线程的两种方式:
(1)继承Thread类创建线程
特点:要重写父类的run()方法,该方法是线程要执行操作任务的方法。线程操作的代码都放入run方法中,然后调用start()方法启动线程
案例1.继承Thread类创建线程
package com.part1;
/**
*1.继承Thread类创建线程,==当前类就是一个线程类
*特点:编写简单,可以直接操作线程,适用于单继承的情况
*操作:使用线程计算打印1-100之间的值
*
*/
public class MyThread extends Thread{
//1.创建记录数的变量
private int count=0;
//2.创建线程执行任务的方法run()
@Override
public void run() {
while(count<100){
count++;
System.out.println("count的值是:"+count);
}
}
//3.编写主线程main()
public static void main(String[] args) {
//3.1 实例化线程对象,==线程已经存在
MyThread mt=new MyThread();
//3.2 使用start启动线程对象=执行run方法内容
mt.start();
}
}
MyThread.java
(2)继承自Runnable接口创建线程
特点:可以使多个线程共用一个Runnable对象,实现资源共享
案例2.实现Runnable接口创建线程
package com.part1;
/**
* 2.实现Runnable接口创建线程
* 特点:
* 当一个线程继承了另一个类,就只能用实现Runnable接口就的方法来创建线程
* 这种方法可以使多个线程之间公用一个Thread对象
* @author pc
*
*/
public class MyRunnable implements Runnable {
//1.定义统计的变量
private int count=0;
//2.定义线程执行的任务方法
@Override
public void run() {
while(count<100){
count++;
System.out.println("count的值是:"+count);
}
}
//3.定义主线程入口
public static void main(String[] args) {
//3.1 创建线程对象
Thread thread=new Thread(new MyRunnable());
//3.2 启动线程
thread.start(); } }
MyRunnable.java
9、线程的状态及线程的生命周期:新生状态、可运行状态、阻塞状态、死亡状态。
(1)新生状态:创建线程对象之后,但是未调用start之前的状态。
(2)可运行状态:调用start()方法启动线程之后的状态
(3)阻塞状态:一种暂时不可运行状态。有可能还会转回可运行状态
(4)死亡状态:当run方法运行完毕后的状态。
10、线程优先级:1-10,1表示最高,可以通过setPriority(int grade)方法更改,
11、Thread类常用的方法:
(1)void run() :执行线程任务操作的方法
(2) void start(): 使线程开始执行的方法
(3) void join() : 等待当前该线程终止,等待join上面的线程执行完再接着刚的执行
案例3.使用join方法暂停执行当前线程
package com.part1;
/**
* 3.使用join方法暂停执行当前线程,等待调用该方法的线程结束后再继续执行本线程
* 操作:在主现场中调用另个一个线程,遇到在调用某个现场后,遇到join时,将某个
* 线程所有操作完成才能接着执行主线程内容
* @author Holly
*
*/
public class MyJoin extends Thread{
//1.定义有参数构造,获取本线程的名字
public MyJoin(String name){
super(name);
} //2.定义线程执行任务的方法
public void run(){
//2.1 循环输出5次该线程对象的名字
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
//3.定义主线程入口
public static void main(String[] args) {
//3.1 主线程循环10次,在第五次时调用该类线程对象,并执行join方法,
for (int i = 0; i < 10; i++) {
if(i==5){
try {
MyJoin mj=new MyJoin("MyJoin");
mj.start();
mj.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" "+i); }
} }
MyJoin.java
案例4.使用join方法实现两个线程间数据传递
package com.part1;
/**
* 4.使用join方法实现两个线程间数据传递
*/
public class MyJoinSetField extends Thread{
//1 定义两个变量
public String value1;
public String value2; //2.定义线程执行操作的方法
public void run(){
value1="value1已经赋值";
value2="value2已经赋值"; }
//3.定义主线程入口
public static void main(String[] args) {
try{
//创建线程对象
MyJoinSetField mjsf=new MyJoinSetField();
//启动线程
mjsf.start();
mjsf.join();
System.out.println("value1:"+mjsf.value1);
System.out.println("value2:"+mjsf.value2);
} catch (InterruptedException e) {
e.printStackTrace();
}
} } MyJoinSetField.java
MyJoinSetField.java
(4) String getNam() :返回该线程的名称
(5)void sleep(long 毫秒) :让正在执行的线程休眠,暂停执行,进入阻塞状态
案例5.sleep使得线程处于休眠状态
package com.part1;
/**
* 5.sleep使得线程处于休眠状态,不可运行状态,也就是阻塞状态,
* 但是一定时候又会执行
* @author pc
*
*/
public class SleepWait {
//1.定义方法使得当前线程自我休眠5秒
public static void bySecond(long s){
try {
//每次睡眠一秒,睡五次
for (int i = 0; i < s; i++) {
System.out.println(i+1+"秒");
//线程自我睡眠1秒
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//2.主线程入口
public static void main(String[] args) {
//2.1提示等待
System.out.println("wait");
//2.2 让主线程等待5秒后再次执行
SleepWait.bySecond(5);
//2.3 提示恢复执行
System.out.println("start"); } }
SleepWait.java
(6)void yield() :暂停当前正在执行的线程对象,执行其他线程,此时处于等待可运行状态
案例6.yield方法暂停线程
6.1 第一个线程类
package com.part1;
/**
* 6.yield方法暂停线程,让优先级比自己高的先执行,
* 但是该现场时处于可运行状态,而不是阻塞状态
* @author pc
*
*/
public class YieldFirstThread extends Thread{
/**
* 线程任务执行的方法
*/
@Override
public void run() {
for (int i = 1; i <=5; i++) {
System.out.println("第一个线程,第"+i+"次运行!");
Thread.yield();
}
} }
YieldFirstThread.java
6.2 第二个线程类
package com.part1;
/**
* 6.yield方法暂停线程,让优先级比自己高的先执行,
* 但是该现场时处于可运行状态,而不是阻塞状态
* @author pc
*
*/
public class YieldSecondThread extends Thread{
/**
* 线程任务执行的方法
*/
@Override
public void run() {
for (int i = 1; i <=5; i++) {
System.out.println("第二个线程,第"+i+"次运行!");
Thread.yield();
}
} }
YieldSecondThread.java
6.3 yield方法的测试类
package com.part1;
/**
* 6.yield方法的测试类
* @author pc
*
*/
public class YieldTest {
/**
*
* @param args
*/
public static void main(String[] args) {
YieldFirstThread firstThread=new YieldFirstThread();
YieldSecondThread secondThread =new YieldSecondThread();
firstThread.start();
secondThread.start();
} }
YieldTest.java
案例7:多线程通信
7.1 储蓄罐ZhuBaoBao
package com.part5;
/**
* 1.储蓄罐
* 资源对象
* @author pc
*
*/
public class ZhuBaoBao {
/**
* 1.储蓄罐余额
*/
private int money; public ZhuBaoBao() {
} public ZhuBaoBao(int money) {
this.money = money;
}
/**
* 2.存钱
* @param money
*/
public void add(int inmoney){
try {
//同步代码块
synchronized (this) {
//储蓄罐现有余额
int oldmoney=this.money;
//让当前线程自我休眠40毫秒,
//然后使得其他线程有机会访问该资源对象
Thread.sleep(40);
//存钱
money=oldmoney+inmoney;
System.out.println("宝哥哥存入"+inmoney+"元,现有余额"+money+"元。"); //通知等待的线程开启获取资源
notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 3.取钱
* 线程同步方法
* @param outmoney
*/
public synchronized void get(int outmoney){
try {
if(outmoney>money){
System.out.println("余额"+money+"林妹妹等待...");
//线程等待
wait();
System.out.println("等待结束,再判断");
}
//储蓄罐现有余额
int oldmoney=money; //让当前线程自我休眠30毫秒,让其他线程有机会访问该资源对象
Thread.sleep(30);
//取钱
money=oldmoney-outmoney;
System.out.println("林妹妹取走"+outmoney+"元,先有余额"+money+"元。"); } catch (InterruptedException e) {
e.printStackTrace();
}
} public int getMoney() {
return money;
} public void setMoney(int money) {
this.money = money;
} @Override
public String toString() {
return "我是猪宝宝,我体内现有余额是:" + money + "元。";
} }
ZhuBaoBao.java
7.2 宝哥哥存钱类
package com.part5;
/**
* 2.宝哥哥存钱类,操作猪宝宝储蓄罐
* @author pc
*
*/
public class BaoGeGe implements Runnable {
//1.引入储蓄罐操作对象
private ZhuBaoBao zhuBaoBao; public BaoGeGe() {
} public BaoGeGe(ZhuBaoBao zhuBaoBao) {
this.zhuBaoBao = zhuBaoBao;
} /**
* 2.线程操作执行方法
*/
@Override
public void run() {
//每次存100 一共存10次
for (int i = 1; i <=10; i++) {
System.out.println("宝哥哥第"+i+"次存钱");
//存钱
zhuBaoBao.add(100);
}
} public ZhuBaoBao getZhuBaoBao() {
return zhuBaoBao;
} public void setZhuBaoBao(ZhuBaoBao zhuBaoBao) {
this.zhuBaoBao = zhuBaoBao;
} }
BaoGeGe..java
7. 3 林妹妹取钱类
package com.part5;
/**
* 3.林妹妹取钱类
* @author pc
*
*/
public class LinMeiMei implements Runnable {
//1.引入操作对象
private ZhuBaoBao zhuBaoBao; public LinMeiMei() {
} public LinMeiMei(ZhuBaoBao zhuBaoBao) {
this.zhuBaoBao = zhuBaoBao;
} /**
* 2.线程任务操作方法
*/
@Override
public void run() {
get(); //取钱 }
/**
* 3.林妹妹取钱
*/
private void get() {
for (int i = 1; i <=10; i++) {
System.out.println("林妹妹第"+i+"次取钱");
zhuBaoBao.get(200);
} } public ZhuBaoBao getZhuBaoBao() {
return zhuBaoBao;
} public void setZhuBaoBao(ZhuBaoBao zhuBaoBao) {
this.zhuBaoBao = zhuBaoBao;
} }
LinMeiMei.java
7.4 测试类
package com.part5.synchronizedlock;
/**
* 4.测试类
*/
public class Test {
public static void main(String[] args) {
try {
//1.获取当前线程
Thread mainThread=Thread.currentThread(); //2.初始化猪宝宝储蓄罐余额1000元
ZhuBaoBao zhubaobao=new ZhuBaoBao(1000); //3.线程宝哥哥和林妹妹操作的是同一个对象猪宝宝
BaoGeGe baoGeGe=new BaoGeGe(zhubaobao);
LinMeiMei linMeiMei=new LinMeiMei(zhubaobao); //4.创建线程类
Thread t1=new Thread(baoGeGe);
Thread t2=new Thread(linMeiMei); //5.启动线程
t1.start();
t2.start(); //6.主线程自我休眠3秒以后以便其他两个线程先执行操作
mainThread.sleep(3000); //7.打印账户余额
System.out.println(zhubaobao); } catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } }
Test.java
7.5 结果
林妹妹第1次取钱
宝哥哥第1次存钱
林妹妹取走200元,先有余额800元。
林妹妹第2次取钱
林妹妹取走200元,先有余额600元。
林妹妹第3次取钱
宝哥哥存入100元,现有余额700元。
宝哥哥第2次存钱
宝哥哥存入100元,现有余额800元。
宝哥哥第3次存钱
宝哥哥存入100元,现有余额900元。
宝哥哥第4次存钱
宝哥哥存入100元,现有余额1000元。
宝哥哥第5次存钱
林妹妹取走200元,先有余额800元。
林妹妹第4次取钱
林妹妹取走200元,先有余额600元。
林妹妹第5次取钱
林妹妹取走200元,先有余额400元。
林妹妹第6次取钱
林妹妹取走200元,先有余额200元。
林妹妹第7次取钱
林妹妹取走200元,先有余额0元。
林妹妹第8次取钱
余额0林妹妹等待...
宝哥哥存入100元,现有余额100元。
宝哥哥第6次存钱
宝哥哥存入100元,现有余额200元。
宝哥哥第7次存钱
宝哥哥存入100元,现有余额300元。
宝哥哥第8次存钱
宝哥哥存入100元,现有余额400元。
宝哥哥第9次存钱
宝哥哥存入100元,现有余额500元。
宝哥哥第10次存钱
宝哥哥存入100元,现有余额600元。
等待结束,再判断
林妹妹取走200元,先有余额400元。
林妹妹第9次取钱
林妹妹取走200元,先有余额200元。
林妹妹第10次取钱
林妹妹取走200元,先有余额0元。
二、Socket通信
2.1 案例1:客户端写入,服务器短读取
package com.part1; import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException; /**
* 1.客户端写入
* @author pc
*
*/
public class SocketTest {
public static void main(String[] args) throws UnknownHostException, IOException {
//1.建立客户端的连接,指定服务器的地址和端口号
Socket socket=new Socket("localhost", 8080);
//2.创建输出流对象
OutputStream os=socket.getOutputStream();
//3.向服务器段写入内容
String info="用户名:Holly,密码:123";
os.write(info.getBytes()); //4.关闭资源
os.close();
socket.close();
} }
SocketTest .java
package com.part1; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket; /**
* 2.服务器段 读取内容
* @author pc
*
*/
public class ServiceSocketTest {
public static void main(String[] args) throws IOException {
//1.创建一个服务器对象并指定监听的端口号
ServerSocket serverSocket=new ServerSocket(8080);
//2.等待客户端触发通信
Socket socket=serverSocket.accept();
//3.创建输入流对象
InputStream is=socket.getInputStream();
//字节流转换为字符流
BufferedReader br=new BufferedReader(new InputStreamReader(is));
//4.循环读取某行内容
String str=br.readLine();
while(str!=null){
System.out.println("我是服务器,客户端信息为:"+str);
str=br.readLine();
}
//5.关闭流
br.close();
is.close();
socket.close();
serverSocket.close();
} }
ServiceSocketTest.java
2.2 案例:2:服务器写入,客户端读取
package com.part2; import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket; /**
* 1.服务器段写入
* @author pc
*
*/
public class ServiceSocketTest {
public static void main(String[] args) throws IOException {
//1.创建一个服务器对象,并指定监听端口号
ServerSocket serverSocket=new ServerSocket(8080);
//2.等待客户端触发通信
Socket socket=serverSocket.accept();
//3.创建输出流对象
OutputStream os=socket.getOutputStream();
//4.向客户端写入内容
String str="你今天萌萌哒!";
os.write(str.getBytes());
//5.释放资源
os.close();
socket.close();
serverSocket.close(); } }
ServiceSocketTest.java
package com.part2; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket; /**
* 2.客户端读取信息
* @author pc
*
*/
public class SocketTest {
public static void main(String[] args) throws IOException {
//1.建立客户端的连接,指定服务器的地址和端口号
Socket socket=new Socket("localhost", 8080);
//2.创建输入流,读取服务器信息
InputStream is=socket.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(is)); //3.循环读取某行内容
String str=br.readLine();
while(str!=null){
System.out.println("我是客户端,服务器的相应为:"+str);
str=br.readLine();
} //4.关闭流
br.close();
is.close();
socket.close(); } }
SocketTest.java
2.3 案例3:客户登录
1. 创建用户类
package com.part3; import java.io.Serializable;
/**
* 1.创建用户类
* @author pc
*
*/
public class User implements Serializable {
private static final long serialVersionUID = -7668755635308104712L;
private String name;
private transient String pwd; public User() {
}
public User(String name, String pwd) {
this.name = name;
this.pwd = pwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
@Override
public String toString() {
return "User [name=" + name + ", pwd=" + pwd + "]";
} }
User.java
2. 登录客户端
package com.part3; import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket; /**
* 2.客户端写入
* 序列化
* @author holly
*
*/
public class LoginClient {
public static void main(String[] args) throws IOException {
//1.建立客户端连接,指定服务器的地址和端口号
Socket socket=new Socket("localhost", 8080);
//2.创建输出流对象
OutputStream os=socket.getOutputStream();
//3.创建序列化对象
ObjectOutputStream oos=new ObjectOutputStream(os);
//4.发送客户端登陆信息=向输出流写入信息,=向服务器写入
User user=new User("holly", "123");
oos.writeObject(user);
//5.释放资源
oos.close();
os.close();
socket.close(); } }
LoginClient.java
3.登录服务器
package com.part3; import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket; /**
* 3.服务器读取
* 反序列化操作
* @author pc
*
*/
public class LoginServer {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1.创建服务器对象,并指定监听的端口号
ServerSocket serverSocket=new ServerSocket(8080);
//2.等待客户端触发通信
Socket socket=serverSocket.accept();
//3.创建输入流对象
InputStream is=socket.getInputStream();
//4.创建反序列对象
ObjectInputStream ois=new ObjectInputStream(is);
//5.读取客户端信息
User user=(User) ois.readObject();
if(user!=null){
System.out.println("我是服务器,客户端信息为:"+user);
}
//6.关闭流
ois.close();
is.close();
socket.close();
serverSocket.close();
} }
LoginServer.java
2.4 案例4:多个客户登录-线程
1.创建用户类
package com.part4; import java.io.Serializable;
/**
* 1.创建用户类
* @author pc
*
*/
public class User implements Serializable {
private static final long serialVersionUID = -7668755635308104712L;
private String name;
private transient String pwd; public User() {
}
public User(String name, String pwd) {
this.name = name;
this.pwd = pwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
@Override
public String toString() {
return "User [name=" + name + ", pwd=" + pwd + "]";
} }
User.java
2.创建登录客户端1
package com.part4; import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket; /**
* 1.客户端写入
* 序列化
* @author Holly
*
*/
public class LoginClient1 {
public static void main(String[] args) throws IOException {
//1.建立客户端连接,指定服务器地址和端口号
Socket socket=new Socket("localhost",8888);
//2.创建输出流对象
OutputStream os=socket.getOutputStream();
//3.创建序列化对象
ObjectOutputStream oos=new ObjectOutputStream(os);
//4.发送客户端信息到服务器,=向服务器写入信息
User user=new User("holly", "123");
oos.writeObject(user);
//5.释放资源
oos.close();
os.close();
socket.close(); } }
LoginClient1.java
3.创建登录客户端2
package com.part4; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket; /**
* 2.客户端写入
* @author pc
*
*/
public class LoginClinet2 {
public static void main(String[] args) throws IOException {
//1.建立客户端连接,指定服务器地址和端口号
Socket socket=new Socket("localhost", 8888);
//2.创建输出流对象
OutputStream os=socket.getOutputStream();
//3.创建序列化对象
ObjectOutputStream oos=new ObjectOutputStream(os);
//4.发送客户端登陆信息,==向输出流写入内容
User user=new User("张福军", "123");
oos.writeObject(user); //5.创建输入流对象
InputStream is=socket.getInputStream();
//6.接受服务器段的响应,即从输入流读取信息
BufferedReader br=new BufferedReader(new InputStreamReader(is)); String str=br.readLine();
while(str!=null){
System.out.println("我是客户端,服务器的响应为:"+str);
}
//7.关闭资源
br.close();
is.close();
oos.close();
os.close();
socket.close(); } }
LoginClinet2.java
4.登陆线程类(客户端)
package com.part4; import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.Socket; /**
* 3.登陆线程类(客户端)
* @author pc
*
*/
public class LoginThread extends Thread{
//1.定义Socket对象
Socket socket=null; //2.每启动一个线程,对应分配一个Socket
public LoginThread(Socket socket) {
this.socket = socket;
}
//3.线程操作执行的方法=启动线程,=响应客户端信息=读取
@Override
public void run() {
try {
//3.1创建输入流对象
InputStream is=socket.getInputStream();
//3.2 创建反序列化对象
ObjectInputStream ois=new ObjectInputStream(is);
//3.3 获取客户端信息=从输入流读取信息
User user=(User) ois.readObject();
if(user!=null){
System.out.println("我是服务器,客户端信息为:"+user);
}
//3.4关闭资源
ois.close();
is.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
LoginThread.java
5.创建登录服务器
package com.part4; import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; /**
* 4.登录服务器
* @author pc
*
*/
public class LoginServer {
public static void main(String[] args) throws IOException {
//1.建立服务器对象,并指定监听端口号
ServerSocket serverSocket=new ServerSocket(8888);
//2.创建Socket客户端连接对象
Socket socket=null;
//3.循环监听一只进行中
while(true){
//3.1 等待客户端触发通信
socket=serverSocket.accept();
//3.2 创建线程对象,来几个客户端创建几个线程,建立几个通信
LoginThread loginThread=new LoginThread(socket);
//3.3 启动线程
loginThread.start();
} } }
LoginServer.java
8.多线程和Socket通信的更多相关文章
- 并发编程~~~多线程~~~计算密集型 / IO密集型的效率, 多线程实现socket通信
一 验证计算密集型 / IO密集型的效率 IO密集型: IO密集型: 单个进程的多线程的并发效率高. 计算密集型: 计算密集型: 多进程的并发并行效率高. 二 多线程实现socket通信 服务器端: ...
- day36——死锁、递归锁、信号量、GIL、多线程实现socket通信、线程池和进程池
day36 死锁现象与递归锁 死锁现象 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这 ...
- 【关于java多线程和socket通信的一些记录】---高并发/高负载/高可用/重入锁
多线程:提高cpu的使用效率,多线程是指在同一程序中有多个顺序流在执行. 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程. 线程:同一类线 ...
- C#socket通信-----多线程
我在之前的socket通信的基础上做了一点改进,使用多线程来使用,程序更加简洁实用.不足之处请指教哦! 话不多说,之前的随笔也有介绍,直接上代码啦! 服务端socket(serverSocket): ...
- Delphi Socket通信及多线程编程总结
http://cxhblog.blog.sohu.com/41930676.html 一.Socket通信: Delphi在ScktComp单元中对WinSock进行了封装,该单元提供了TAbstra ...
- Java多线程技术:实现多用户服务端Socket通信
目录 前言回顾 一.多用户服务器 二.使用线程池实现服务端多线程 1.单线程版本 2.多线程版本 三.多用户与服务端通信演示 四.多用户服务器完整代码 最后 前言回顾 在上一篇<Java多线程实 ...
- 基于多线程的TCP socket通信经典案例
服务器端 package com.thinkvenus.study.socket; import java.io.BufferedReader; import java.io.IOException; ...
- .net平台下C#socket通信(上)
在开始介绍socket前先补充补充基础知识,在此基础上理解网络通信才会顺理成章,当然有基础的可以跳过去了.都是废话,进入正题. TCP/IP:Transmission Control Protocol ...
- Python拾忆--多线程的socket服务器
阳光明媚的午后,想想最近要开始从写Java到写Python了,就随手打开电脑来体验一下Python与Java之间的不同吧~ 记得我还在上大二的时候,那个时候才开始学Java,最感兴趣的就是Java书最 ...
随机推荐
- Tomcat启动极慢问题
启动后,catalina.out日志中会有如下打印: INFO: Creation of SecureRandom instance ,] milliseconds 具体原因,有兴趣的可以自己百度一下 ...
- JSTL标签库--核心标签库
->JSTL的使用和EL表达式是分不开的 ->JSTL标签库分为5类 1.核心标签库(这里只介绍该标签库) 2.I18N格式化标签库 3.SQL标签库 4.XML标签库 5.函数标签库 - ...
- deployd使用归纳
deployd:一个生成后端数据的软件,简单的说就是大部分的前端不会后端,即使会也很难在深入到数据库进行设置一些前端所需数据的创建与查询的后端程序的书写,所以此时就是deployd大显身手的时候了. ...
- mysql 保存emoji时报,数据库报错:Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x82\xF0\x9F...' for column 'review' at row 1
错误原因:我们可以看到错误提示中的字符0xF0 0x9F 0x98 0x84 ,这对应UTF-8编码格式中的4字节编码(UTF-8编码规范).正常的汉字一般不会超过3个字节,为什么为出现4个字节呢?实 ...
- Python 代码规范
命名 module_name, package_name, ClassName, method_name, ExceptionName, function_name, GLOBAL_VAR_NAME, ...
- top batch output
echo 3 > sudo tee /proc/sys/vm/drop_caches top -d30 -bn20 > a
- IOS 加载网络图片2
//1. NSData dataWithContentsOfURL // [self.icon setImage:[UIImage imageWithData:[NSData dataWithCont ...
- iOS程序崩溃相关的处理办法
一.bug追踪 1.捕获异常:Exception breakpoint 步骤: 2.终止调用:Symbolic breakpoint 步骤:前两步和一 基本是一样的,不截图了,只是在第二步选择的时候选 ...
- box-sizing的不同属性值间的区别
box-sizing:值为 border-box时,其含义为:表示元素的宽度与高度包括内部补白区域(指border和padding)与边框的宽度与高度:值为content-box时,其含义正其前者相反 ...
- 【实验室笔记】C#的Socket客户端接收和发送数据
采用socket发送和接收数据的实验中,服务器采用的是网络助手作为模拟服务器端. 客户端程序流程: 应用的命名空间: using System.Net; using System.Net.Socket ...