一、通过模拟网络延迟,解决同步的问题、
package com.zxf.demo; public class G01 implements Runnable{ private int num=10; private int count=0; @Override public void run() { // TODO Auto-generated method stub while (true) { count++; num--; System.out.println(Thread.currentThread().getName()+"买到了第"+count+"条裤子,还剩"+num+"条裤子"); //模拟网络延迟 让进程睡眠一会 1秒 try { Thread.sleep(300); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (num<=0) { break; } } } public static void main(String[] args) { G01 g1 = new G01(); Thread t1 = new Thread(g1,"卢本伟"); Thread t2 = new Thread(g1,"马飞飞"); Thread t3 = new Thread(g1,"大司马"); Thread t4 = new Thread(g1,"骚男"); t1.start(); t2.start(); t3.start(); t4.start(); } }
这样写是有问题的 多个进程轮番执行,不能保证每个人买到的东西的唯一性
解决方式?
1.把可能产生的数据安全问题的代码 锁起来, 被锁定的代码就变成单线程的!
package com.zxf.demo; public class G01 implements Runnable{ private int num=10; private int count=0; @Override public void run() { // TODO Auto-generated method stub while (true) { // 通过synchronized (this){} 将会出问题的部分 锁在这里 ,这里就变了单线程模式 就不会出错! synchronized (this) { if (num<=0) { break; } count++; num--; System.out.println(Thread.currentThread().getName()+"买到了第"+count+"条裤子,还剩"+num+"条裤子"); } //模拟网络延迟 让进程睡眠一会 1秒 try { Thread.sleep(300); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { G01 g1 = new G01(); Thread t1 = new Thread(g1,"卢本伟"); Thread t2 = new Thread(g1,"马飞飞"); Thread t3 = new Thread(g1,"大司马"); Thread t4 = new Thread(g1,"骚男"); t1.start(); t2.start(); t3.start(); t4.start(); } }
2.同步方法 就是在方法的返回值类型前边加上 synchronize将该方法内部的代码 全部锁起来
package com.zxf.demo; public class G01 implements Runnable{ private int num=10; private int count=0; @Override public void run() { // TODO Auto-generated method stub while (true) { if (!buy()) { // 调用buy的方法 不满足结果 结束循环 break; } //模拟网络延迟 让进程睡眠一会 1秒 try { Thread.sleep(300); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //同步方法 定义一个方法 需要在方法的返回值类型 前边加上 synchronized 关键字。 public synchronized boolean buy() { if (num<=0) { return false; } num--; count++; System.out.println(Thread.currentThread().getName()+"买到了第"+count+"条裤子,还剩"+num+"条裤子"); return true; } public static void main(String[] args) { G01 g1 = new G01(); Thread t1 = new Thread(g1,"卢本伟"); Thread t2 = new Thread(g1,"马飞飞"); Thread t3 = new Thread(g1,"大司马"); Thread t4 = new Thread(g1,"骚男"); t1.start(); t2.start(); t3.start(); t4.start(); } }