安全问题的方法"/>
解决多线程安全问题的方法
java基础 解决多线程安全问题的方法
- synchronized 代码块
- synchronized 方法
- Lock 锁
下面以一个卖票的程序对知识点进行演示。
- synchronized 代码块
格式 synchronized (){ }
方法实现如下:
public class SynchronizedDemo {public static void main(String[] args){//new一个Runnable接口的实现类RunnableImpl runnable = new RunnableImpl();//new三个新线程Thread thread = new Thread(runnable);Thread thread1 = new Thread(runnable);Thread thread2 = new Thread(runnable);//设置各个线程的名字thread.setName("马云");thread1.setName("王健林");thread2.setName("王建国");//开启线程thread.start();thread1.start();thread2.start();}
}
public class RunnableImpl implements Runnable {private int ticket = 10;private int count = 0;//new 一个对象(随意的对象),作为synchronized代码块的接收锁,关于这个知识点有问题的可以先看知识点3---Lock锁的讲解作为理解Object obj = new Object();@Overridepublic void run() {while (true) {if (ticket < 1)break;//接收Object类作为接收锁,三个线程抢夺一个接收锁,当其中一个线程争夺到使用权,其他线程进行等待synchronized (obj){if (ticket > 0) {ticket--;count++;System.out.println(Thread.currentThread().getName() + "正在卖第" + count + "张票。");try {//使当前线程沉睡100毫秒Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}}}}
运行结果:
马云正在卖第1张票。
王健林正在卖第2张票。
王建国正在卖第3张票。
王建国正在卖第4张票。
王建国正在卖第5张票。
王建国正在卖第6张票。
王健林正在卖第7张票。
马云正在卖第8张票。
王健林正在卖第9张票。
王健林正在卖第10张票。
再次运行:
马云正在卖第1张票。
马云正在卖第2张票。
马云正在卖第3张票。
王建国正在卖第4张票。
王建国正在卖第5张票。
王健林正在卖第6张票。
王健林正在卖第7张票。
王健林正在卖第8张票。
王健林正在卖第9张票。
王健林正在卖第10张票。Process finished with exit code 0
2. synchronized 方法
格式:修饰符 synchronized 返回值类型 方法名 (参数列表){ }
方法实现如下:
public class SynchronizedDemo {public static void main(String[] args){RunnableImpl runnable = new RunnableImpl();//开启三个新线程Thread thread = new Thread(runnable);Thread thread1 = new Thread(runnable);Thread thread2 = new Thread(runnable);thread.setName("马云");thread1.setName("王健林");thread2.setName("王建国");thread.start();thread1.start();thread2.start();}
}
public class RunnableImpl implements Runnable {private int ticket = 10;private int count = 0;@Overridepublic void run() {while (true) {if (ticket < 1)break;synchronizedMethod();}}//用synchronized关键字创建方法public synchronized void synchronizedMethod(){if (ticket > 0) {ticket--;count++;System.out.println(Thread.currentThread().getName() + "正在卖第" + count + "张票。");try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}}
运行结果:
马云正在卖第1张票。
马云正在卖第2张票。
马云正在卖第3张票。
马云正在卖第4张票。
马云正在卖第5张票。
王建国正在卖第6张票。
王健林正在卖第7张票。
王健林正在卖第8张票。
王建国正在卖第9张票。
王建国正在卖第10张票。Process finished with exit code 0
再次运行:
马云正在卖第1张票。
马云正在卖第2张票。
马云正在卖第3张票。
马云正在卖第4张票。
马云正在卖第5张票。
王建国正在卖第6张票。
王建国正在卖第7张票。
王建国正在卖第8张票。
王建国正在卖第9张票。
王建国正在卖第10张票。Process finished with exit code 0
3. Lock 锁
java.util.concurrent.locks包下的Lock接口。
public void lock():加同步锁。
public void unlock():释放同步锁。
方法实现如下:
public class LockDemo {public static void main(String[] args){RunnableImpl runnable = new RunnableImpl();//开启三个新线程Thread thread = new Thread(runnable);Thread thread1 = new Thread(runnable);Thread thread2 = new Thread(runnable);thread.setName("马云");thread1.setName("王健林");thread2.setName("王建国");thread.start();thread1.start();thread2.start();}
}
public class RunnableImpl implements Runnable {private int ticket = 10;private int count = 0;//new一个Lock接口的实现类ReentrantLock(),利用多态对Lock接口中的方法 进行使用Lock lock = new ReentrantLock();@Overridepublic void run() {while (true) {if (ticket < 1)break;//加同步锁,三个线程随机一个进行一下代码,其他两个线程进行等待lock.lock();if (ticket > 0) {ticket--;count++;System.out.println(Thread.currentThread().getName() + "正在卖第" + count + "张票。");try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}//释放同步锁lock.unlock();}}
运行结果:
马云正在卖第1张票。
马云正在卖第2张票。
马云正在卖第3张票。
马云正在卖第4张票。
马云正在卖第5张票。
王健林正在卖第6张票。
王健林正在卖第7张票。
王健林正在卖第8张票。
王健林正在卖第9张票。
王健林正在卖第10张票。Process finished with exit code 0
再次运行:
马云正在卖第1张票。
王健林正在卖第2张票。
王健林正在卖第3张票。
王建国正在卖第4张票。
王建国正在卖第5张票。
王建国正在卖第6张票。
王建国正在卖第7张票。
王建国正在卖第8张票。
王建国正在卖第9张票。
王建国正在卖第10张票。Process finished with exit code 0
更多推荐
解决多线程安全问题的方法
发布评论