目录
多线程
三种实现方式
1.extends Thread
MyThread myThread1 = new MyThread();
2.implements Runnable
MyRunnable myRunnable = new MyRunnable();
Thread thread1 = new Thread(myRunnable);
3.implement Callable<T>
MyCallable myCallable = new MyCallable();
FutureTask<T> futureTask1 = new FutureTask<>(myCallable);
Thread thread1 = new Thread(futureTask1);
常用方法
thread1.start();//启动线程
Thread.currentThread()//获取调用对象
getNamesetName//获取设置线程名字
Thread.sleep(1000);//线程睡眠
thread1.getPriority();//获取线程优先级
thread1.setPriority();//设置线程优先级
thread1.setDaemon(true);//设置守护线程
线程安全问题
出现原因 : 多个线程操作共享数据
解决方法 :
1.同步代码块 (加锁)
synchronized (任意对象) {}
//保证锁对象的唯一
2.同步方法 (方法加锁)
public synchronized void T1() {}
3.Lock锁 (自定义)
ReentrantLock lock = new ReentrantLock();
lock.lock();
lock.unlock();
线程池
创建默认线程池
ExecutorService service = Executors.newCachedThreadPool();
service.submit(()->{
System.out.println(Thread.currentThread().getName()+"执行");
});
创建自定义线程池
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
5,//核心线程数量
10,//最大线程数
2,//空闲时间线程存活时间(值)
TimeUnit.SECONDS,//空闲时间线程存活时间(单位)
new ArrayBlockingQueue<>(1),//创建线程工厂
Executors.defaultThreadFactory());//拒绝策略
volatile
public volatile static int i = 100;//强制线程每次使用的时候,都看一下共享区域的值
原子性
多个操作是一个不可分割的整体;volatile不能保证原子性,synchronized可以
i++;两步操作不可保证原子性,解决办法:
AtomicInteger atomicInteger = new AtomicInteger();
ConcurrentHashMap
因为:
HashMap 不能保证原子性
Hashtable 锁太多效率太低
底层原理 二次哈希
初始数组不变,0索引存长度为2的小数组,添加数据时:其他索引存小哈希表的地址值
和哈希表一致,1.7以前用链表,1.8之后长度大于8时,用红黑树
网络编程
三要素
IP : 设备在网络中的地址,唯一标识
端口 : 应用程序在设备中的唯一标识(0~1023被占用,自己使用用1024以上的)
协议 : 数据在网络中的传输规则,常见的协议有UDP和TCP
InetAddress
将IP地址封装为该类对象
InetAddress address = InetAddress.getByName("127.0.0.1");//可传入IP地址和本机名
String s1 = address.getHostAddress();//返回本机IP
String s2 = address.getHostName();//返回本机名
UDP
UDP面向无连接,速度快,一次最多传输64k,数据不安全,容易丢失数据
发送端
DatagramSocket ds = new DatagramSocket();// 创建传输服务的发送或接收点
byte[] bytes = "Hello".getBytes();// 字符串转化为字节数组
InetAddress address = InetAddress.getByName("127.0.0.1");// IP 地址转化为 InetAddress 对象
int a = 10000;// 端口号
DatagramPacket dp1 = new DatagramPacket(bytes,bytes.length,address,a);// 数据打包
ds.send(dp1);// 真正的传输
ds.close();
接收端
DatagramSocket ds = new DatagramSocket(10000);//从 10000 端口接收
byte[] bytes = new byte[1024];//创建容器
DatagramPacket dp = new DatagramPacket(bytes,bytes.length);//接收数据
ds.receive(dp);//阻塞等待
System.out.println(new String(bytes));//把字节数组转化为String,并打印
ds.close();
TCP
三次握手,四次挥手,通过IO流传输,无大小限制,速度较慢,数据安全
客户端
Socket socket = new Socket("127.0.0.1",1000);//创建 Socket 对象,用于连接
OutputStream outputStream = socket.getOutputStream();//创建 IO 流用于写入数据
outputStream.write("Hello".getBytes());
outputStream.close();
socket.close();
服务器端
ServerSocket serverSocket = new ServerSocket(10000);//创建 Socket 对象,用于连接
Socket accept = serverSocket.accept();//等待连接
InputStream inputStream = accept.getInputStream();
int b;
while ((b = inputStream.read()) != -1) {
System.out.print((char) b);
}
accept.close();
serverSocket.close();
不由自己new,而是通过socket对象获取的,可以称之为“网络IO流”,write方法可以通过网络跨电脑发送数据