
第一个解决线程安全问题的方法: 使用同步代码块
格式:
已同步(锁定对象){
可能存程安全问题的代码(访问共享数据的代码)
}

注意: 代码块中的锁对象可以是任何对象线程安全问题代码,但是必须确保多个线程使用同一对象
锁定对象的作用是锁定同步代码块,并且一次只能在同步代码块中执行一个线程
package com.fgy.demo02; /** * 实现卖票案例 */ public class RunnableImpl implements Runnable { private int ticket = 100; Object obj = new Object(); @Override public void run() { while (true) { synchronized (obj) { if (ticket > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在买第" + ticket + "张票"); ticket--; } } } } }
package com.fgy.demo02; public class Demo01Ticket { public static void main(String[] args) { RunnableImpl run = new RunnableImpl(); new Thread(run).start(); new Thread(run).start(); new Thread(run).start(); } }


解决线程安全问题的第二种方案: 使用同步方法
使用步骤:
1. 提取访问共享数据的代码并将其放在方法中
2. 将同步修饰符添加到方法中
格式:

修饰符同步的返回值类型方法名称(...){
可能存程安全问题的代码(访问共享数据的代码)
}
同步方法的锁定对象是:
静态同步方法的锁对象不能是this线程安全问题代码,因为它是在创建对象之后创建的,并且静态方法优先于该对象

静态方法的锁对象是此类的类文件对象
package com.fgy.demo03; /** * 实现卖票案例 */ public class RunnableImpl implements Runnable { private int ticket = 100; @Override public void run() { while (true) { payTicket(); } } public synchronized void payTicket() { if (ticket > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在买第" + ticket + "张票"); ticket--; } } }
第三个解决线程安全问题的方法: 使用锁锁
使用步骤:
1. 在成员的位置创建一个ReenterantLock对象
2. 在可能存在安全问题的代码之前,在Lock接口中调用方法lock()以获得锁.
3. 在可能存在安全问题的代码后,在Lock接口中调用方法unlock()释放锁.
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-190872-1.html
国内的啤酒也是淡如水