JAVA 高并发
程序员文章站
2023-10-16 23:45:46
写在前面 一切技术都是纸老虎,技术就是一层膜,捅破了就什么也不是 多线程两种实现方式 继承 Thread 类,实现 run 方法将需要多线程启动的功能代码放在 run 方法内 该方式有 isinterrupted 标志位, 可以根据该标志位在另一个能够获取到该线程的代码块中that.interrup ......
写在前面
一切技术都是纸老虎,技术就是一层膜,捅破了就什么也不是
多线程两种实现方式
- 继承 thread 类,实现 run 方法将需要多线程启动的功能代码放在 run 方法内 该方式有 isinterrupted 标志位,
可以根据该标志位在另一个能够获取到该线程的代码块中that.interrupt 实现中断,但是是否真的中断则由that线程决定 - 实现 runnable 接口,覆写 run 方法将需要多线程启动的功能代码放在 run 方法内,注意这里没有 isinterrupted 标志位
实际上在一个线程中停止另一个线程可以用 concurrent 包中的 cancel 方法,这个 跟 python 简直一毛一样啊啊啊
executorservice 接口下固定大小线程池 (fixed),动态变化(cached) , 以及只有单个(single)线程的 线程池
// t1.start() 永远使用 start --》 start0 (本地方法) 去启动线程 而非 调用 run 方法 // 这里记得 t1.join() 是等待t1线程执行完成才会继续往下执行 // t1.setdaemon(true) 设置为守护线程,也就是不那么重要的,jvm 在所有非守护线程执行完成后就会退出,垃圾回收就是一个守护线程 // 虽然我们以后使用 concurrent 包来进行并发,但是基础原理一定要掌握牢固 // 进程 六种状态 new | running | blocking | waiting | timed waiting|terminiated thread 常用方法 构造方法 thread(runnable target,string name) 静态方法: thread.currentthread().getname() thread.sleep(1000) // java 中 单位是毫秒 所以 1000ms = 1 s,python 中直接是 秒
线程安全同步机制 synchronized 同步代码快, 同步方法,可重入锁,可重入读写锁
加入 synchronized 同步方法, synchronized 这个方式不如 可重入锁安全,被synchronized修饰的要么获得锁,要么永远等待下去
public class counter { private int value; public synchronized void inc(int m){ this.value+=m; } public synchronized void dec(int m){ this.value-=m; } }
引入可重入锁即可以在同一个线程内多次获取该锁
package com.ghc.test; import java.util.concurrent.locks.lock; import java.util.concurrent.locks.reentrantlock; public class counter { private lock lock = new reentrantlock(); private int value; public void inc(int m){ if(lock.trylock()){ try{ this.value+=m; }finally{ lock.unlock(); } } } public void dec(int m){ if(lock.trylock()){ try{ this.value-=m; }finally { lock.unlock(); } } } public int getvalue(){ lock.lock(); try{ return this.value; }finally { lock.unlock(); } } public static void main(string [] args) throws interruptedexception{ system.out.println(thread.currentthread().getname()+" start..."); new thread(()->{ system.out.println(thread.currentthread().getname()+" start..."); try{ thread.sleep(1000); }catch (interruptedexception e){} system.out.println(thread.currentthread().getname()+" end..."); },"download thread").start(); thread.sleep(500); system.out.println(thread.currentthread().getname()+" end..."); } }
引入 可重入 读写锁,因为 可以同时读 , 不可同时写入 或者说不可同时读写
引入 可重入读写锁在同时写入的时候会加锁进行同步,而在同时读取的时候则不会提高并发性能
package com.ghc.test; import java.util.concurrent.locks.reentrantreadwritelock; public class counter { private final reentrantreadwritelock lock = new reentrantreadwritelock(); private final reentrantreadwritelock.readlock readlock = lock.readlock(); private final reentrantreadwritelock.writelock writelock = lock.writelock(); private int value; public void inc(int m){ // 写 锁 writelock.lock(); try{ this.value+=m; }finally { writelock.unlock(); } } public void dec(int m){ // 读锁 readlock.lock(); try{ this.value-=m; }finally { readlock.unlock(); } } }