多线程安全问题的解决方法 三种方法: 同步代码块: synchronized(obj) { //obj表示同步监视器,是同一个同步对象 /**..... TODO SOMETHING */ }
同步方法 格式: 在方法上加上synchronized修饰符即可。(一般不直接在run方法上加!) synchronized 返回值类型 方法名(参数列表) { /**..... TODO SOMETHING */ } 同步方法的同步监听器其实的是 this 静态方法的同步 同步方法 同步代码块 static不能和 this连用 静态方法的默认同步锁是当前方法所在类的.class对象 同步锁 jkd1.5后的另一种同步机制: 通过显示定义同步锁对象来实现同步,这种机制,同步锁应该使用Lock对象充当。 在实现线程安全控制中,通常使用ReentrantLock(可重入锁)。使用该对象可以显示地加锁和解锁。 具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。 public class X { private final ReentrantLock lock = new ReentrantLock(); //定义需要保证线程安全的方法 public void m(){ //加锁 lock.lock(); try{ //... method body }finally{ //在finally释放锁 lock.unlock(); } } } 修改后的例子: //同步代码块 package july7; class SellDemo implements Runnable{ private int num = 50; @Override public void run() { for (int i = 0; i < 200; i++) { synchronized (this) { if(num > 0){ try { //因为它不可以直接调用getName()方法,所以必须要获取当前线程。 Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"卖出第"+num--+"张票!"); } } } } } public class Demo3 { public static void main(String[] args) { SellDemo s = new SellDemo(); new Thread(s,"A").start(); new Thread(s,"B").start(); new Thread(s,"C").start(); } } //同步方法 package july7; //同步方法 class FinalDemo1 implements Runnable { private int num = 50; @Override public void run() { for (int i = 0; i < 100; i++) { gen(); } } public synchronized void gen() { for (int i = 0; i < 100; i++) { if (num > 0) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "卖出了第" + num-- + "张票!"); } } } } public class Demo6 { public static void main(String[] args) { FinalDemo1 f = new FinalDemo1(); new Thread(f, "A").start(); new Thread(f, "B").start(); new Thread(f, "C").start(); } } //线程同步锁 package july7; import java.util.concurrent.locks.ReentrantLock; //同步锁 class FinalDemo2 implements Runnable { private int num = 50; private final ReentrantLock lock = new ReentrantLock(); @Override public void run() { for (int i = 0; i < 100; i++) { gen(); } } public void gen() { lock.lock(); try{ //for (int i = 0; i < 100; i++) { if (num > 0) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "卖出了第" + num-- + "张票!"); } //} }finally{ lock.unlock(); } } } public class Demo7 { public static void main(String[] args) { FinalDemo2 f = new FinalDemo2(); new Thread(f, "A").start(); new Thread(f, "B").start(); new Thread(f, "C").start(); }
}
|