第一个解决线程安全问题的方法: 使用同步代码块
格式:
已同步(锁定对象){
可能存程安全问题的代码(访问共享数据的代码)
}
注意: 代码块中的锁对象可以是任何对象线程安全问题代码,但是必须确保多个线程使用同一对象
锁定对象的作用是锁定同步代码块,并且一次只能在同步代码块中执行一个线程
packagecom.fgy.demo02;/*** 实现卖票案例*/
public class RunnableImpl implementsRunnable {private int ticket = 100;
Object obj= newObject();
@Overridepublic voidrun() {while (true) {(obj) {if (ticket > 0) {try{
Thread.sleep(100);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+ "正在买第" + ticket + "张票");
ticket--;
}
}
}
}
}
packagecom.fgy.demo02;public classDemo01Ticket {public static voidmain(String[] args) {
RunnableImpl run= newRunnableImpl();newThread(run).start();newThread(run).start();newThread(run).start();
}
}
解决线程安全问题的第二种方案: 使用同步方法
使用步骤:
1. 提取访问共享数据的代码并将其放在方法中
2. 将同步修饰符添加到方法中
格式:
修饰符同步的返回值类型方法名称(...){
可能存程安全问题的代码(访问共享数据的代码)
}
同步方法的锁定对象是:
静态同步方法的锁对象不能是this线程安全问题代码,因为它是在创建对象之后创建的,并且静态方法优先于该对象
静态方法的锁对象是此类的类文件对象
packagecom.fgy.demo03;/*** 实现卖票案例*/
public class RunnableImpl implementsRunnable {private int ticket = 100;
@Overridepublic voidrun() {while (true) {
payTicket();
}
}public synchronized voidpayTicket() {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()释放锁.
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-190872-1.html