Java线程(Lock接口,重入锁,读写锁)
Lock接口、重入锁
JDK1.5加入,与synchronized相比较,显示、定义、结构更加灵活。即性能更加优越。
常用方法:
void lock() 获取锁,如果锁被占用,则等待。
Boolean Trylock() 尝试获取锁,成功则返回true,锁被占用则等待,不阻塞
Void unlock() 释放锁
在锁之中调用一个锁,ReentrantLock,类似于互斥锁synchronized。
需求说明,将hello\world两个词加入拥有五个位置的数组当中。
代码示例:
MyList类:
import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Mylist { private Lock lock=new ReentrantLock(); private String[] str={"A","B","","",""}; private int count=2; public void add(String value){ lock.lock(); str[count]=value; //防止进程太快 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public String[] getStr(){ return str; } }
MyList的测试类:
1 import java.util.Arrays; 2 3 public class TestMylist { 4 public static void main(String[] args) throws Exception{ 5 Mylist mylist = new Mylist(); 6 Runnable runnable=new Runnable() { 7 @Override 8 public void run() { 9 mylist.add("hello"); 10 } 11 }; 12 Runnable runnable2=new Runnable() { 13 @Override 14 public void run() { 15 mylist.add("world"); 16 } 17 }; 18 19 Thread t1=new Thread(runnable); 20 Thread t2=new Thread(runnable2); 21 22 t1.start(); 23 t2.start(); 24 25 t1.join(); 26 t2.join(); 27 28 System.out.println(Arrays.toString(mylist.getStr())); 29 30 31 } 32 }
在锁之中调用一个锁,ReentrantLock,类似于互斥锁synchronized。
卖票案例的ReentrantLock写法:
Ticket类:
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Ticket implements Runnable{ private int ticket =100; private Lock lock = new ReentrantLock(); @Override public void run() { while (true){ lock.lock(); try { if (ticket<0){ break; } System.out.println(Thread.currentThread().getName()+"卖了第:"+ticket+"张票"); ticket--; } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } } }
对于Ticket的测试类:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TestTicket { public static void main(String[] args) { Ticket ticket=new Ticket(); ExecutorService es=Executors.newFixedThreadPool(4); for (int i=0;i<=4;i++){ es.submit(ticket); } es.shutdown(); } }
读写锁
读锁不互斥,写锁互斥。运行效率高
互斥规则:
写-写:互斥,阻塞
读-写:互斥,读阻塞写,写阻塞读
读-读:不互斥,不阻塞
在读操作远远高于写操作的环境中,可在保障线程安全的情况下,提高运行效率。
代码示例:
ReentrantReadWriteLock:
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReadWriteDemo { // 创建读写锁 private ReentrantReadWriteLock rr1 = new ReentrantReadWriteLock(); // 获取读锁 private ReentrantReadWriteLock.ReadLock readLock=rr1.readLock(); // 创建写锁 private ReentrantReadWriteLock.WriteLock writeLock=rr1.writeLock(); private String value; public String getValue(){ readLock.lock(); try { try { // 拿到数据前休眠一会,让程序变慢 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("读取:"+this.value); return this.value; } finally { readLock.unlock(); } } public void setValue(String value){ writeLock.lock(); try { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("写入:"+value); this.value=value; } finally { writeLock.unlock(); } } }
测试类:
import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TestReadWriteLock { public static void main(String[] args) { ReadWriteDemo readWriteDemo=new ReadWriteDemo(); // 创建线程池 ExecutorService es = Executors.newFixedThreadPool(20); Runnable read = new Runnable() { @Override public void run() { readWriteDemo.getValue(); } }; Runnable write = new Runnable() { @Override public void run() { //产生一个1000以内的随机数作为张三的年龄 readWriteDemo.setValue("张三:"+new Random().nextInt(100)); } }; long start=System.currentTimeMillis(); // 分配18读取任务 for (int i = 0;i < 18;i++){ es.submit(read); } for (int j = 0; j < 2;j++ ){ es.submit(write); } es.shutdown();//关闭线程 while(!es.isTerminated()){//相当于机器的空转,等待上面的任务全部完成 } long end = System.currentTimeMillis(); System.out.println("用时="+(end-start)); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术