Java多线程的临界资源问题
Posted ggrrbb
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程的临界资源问题相关的知识,希望对你有一定的参考价值。
临界资源问题的原因:某一个线程在对临界资源进行访问时,还没来得及完全修改临界资源的值,临界资源就被其他线程拿去访问,导致多个线程访问同一资源。直观表现为打印结果顺序混乱。
解决方法:加锁
静态方法中用类锁,非静态方法中用对象锁。
1.同步代码段:synchronized(){...}
2.同步方法:使用关键字synchronized修饰的方法
3.使用显式同步锁ReentrantLock
锁池描述的即为锁外等待的状态
方法一:同步代码段:synchronized(){...}
public class SourceConflict { public static void main(String[] args) { //实例化4个售票员,用4个线程模拟4个售票员 Runnable r = () -> { while (TicketCenter.restCount > 0) { synchronized(" ") { if (TicketCenter.restCount <= 0) { return; } System.out.println(Thread.currentThread().getName() + "卖出一张票,剩余" + --TicketCenter.restCount + "张票"); } } }; //用4个线程模拟4个售票员 Thread thread1 = new Thread(r, "thread-1"); Thread thread2 = new Thread(r, "thread-2"); Thread thread3 = new Thread(r, "thread-3"); Thread thread4 = new Thread(r, "thread-4"); //开启线程 thread1.start(); thread2.start(); thread3.start(); thread4.start(); } } //实现四名售票员共同售票,资源共享,非独立 //Lambda表达式或匿名内部类内部捕获的局部变量必须显式的声明为 final 或实际效果的的 final 类型,而捕获实例或静态变量是没有限制的 class TicketCenter{ public static int restCount = 100; }
方法二:同步方法,即使用关键字synchronized修饰的方法
1 public class SourceConflict2 { 2 public static void main(String[] args) { 3 //实例化4个售票员,用4个线程模拟4个售票员 4 5 Runnable r = () -> { 6 while (TicketCenter.restCount > 0) { 7 sellTicket(); 8 } 9 }; 10 11 //用4个线程模拟4个售票员 12 Thread thread1 = new Thread(r, "thread-1"); 13 Thread thread2 = new Thread(r, "thread-2"); 14 Thread thread3 = new Thread(r, "thread-3"); 15 Thread thread4 = new Thread(r, "thread-4"); 16 17 //开启线程 18 thread1.start(); 19 thread2.start(); 20 thread3.start(); 21 thread4.start(); 22 23 } 24 25 private synchronized static void sellTicket() { 26 if (TicketCenter.restCount <= 0) { 27 return; 28 } 29 System.out.println(Thread.currentThread().getName() + "卖出一张票,剩余" + --TicketCenter.restCount + "张票"); 30 } 31 } 32 33 class TicketCenter{ 34 public static int restCount = 100; 35 }
方法三:使用显式同步锁ReentrantLock
1 import java.util.concurrent.locks.ReentrantLock; 2 3 public class SourceConflict3 { 4 public static void main(String[] args) { 5 //实例化4个售票员,用4个线程模拟4个售票员 6 7 //显式锁 8 ReentrantLock lock = new ReentrantLock(); 9 Runnable r = () -> { 10 while (TicketCenter.restCount > 0) { 11 lock.lock(); 12 if (TicketCenter.restCount <= 0) { 13 return; 14 } 15 System.out.println(Thread.currentThread().getName() + "卖出一张票,剩余" + --TicketCenter.restCount + "张票"); 16 lock.unlock(); 17 } 18 }; 19 20 //用4个线程模拟4个售票员 21 Thread thread1 = new Thread(r, "thread-1"); 22 Thread thread2 = new Thread(r, "thread-2"); 23 Thread thread3 = new Thread(r, "thread-3"); 24 Thread thread4 = new Thread(r, "thread-4"); 25 26 //开启线程 27 thread1.start(); 28 thread2.start(); 29 thread3.start(); 30 thread4.start(); 31 32 } 33 }
35 class TicketCenter{
36 public static int restCount = 100;
37 }
以上是关于Java多线程的临界资源问题的主要内容,如果未能解决你的问题,请参考以下文章