1.并发: 在我们的操作系统中,同一个时间点,有N个线程都想访问同一个程序!但是cpu只能运行一个! 这种情况就是! 多个线程在 同一个时间点 访问同一个资源,会引发线程不安全的问题! 怎么解决这种不安全的问题?? 01.设置同步代码块 02.设置同步方法 使用的关键字 synchronized 解决! 注意点: 01.在同一个时间点,只能有一个线程进入 synchronized代码块或者方法 02.当一个线程访问 synchronized代码块的时候,其他的synchronized代码块也会被锁定! 03.当一个线程访问 synchronized代码块的时候,其他的线程可以访问非synchronized修饰代码块! 2.Runnable Callable 的区别 Future接口 01.Runnable接口中只有一个方法 public abstract void run(); 没有返回值 没有声明异常 02.Callable接口中只有一个方法 V call() throws Exception; 有返回值 有声明异常 03.Callable 接口中的call()的返回值可以用 Future对象来接收 3. Future是一种思想: 1 2 3 4四个人在排队买煎饼! 234是不是需要等待! 假如一人需要等待5分钟! 第四个人4需要等待15分钟! 按照我们现在讲的线程! 123得到煎饼,4必须等待15分钟之后才能得到! 中间4不能离开队列,4白白等待15分钟! Future的核心: 1 2 3 4四个人在排队买煎饼! 假如一人需要等待5分钟! 4知道自己需要等待15分钟! 这时候4可以利用这15分钟去做别的事情! 123买完煎饼之后,4会得到通知,然后回来购买煎饼!
4.同步锁:
/** * 售票的线程类 实现同步 */ public class SynchronizedSale implements Runnable { // 定义总票数 private int counts = 10000; // 定义出售票的下标 private int num = 0; @Override public void run() { while (true) { /** * 在多个线程并发访问我们这个run()的时候 * 只能有一个线程进入我们这个synchronized 同步代码块! * 第一个线程执行完毕之后,之后的线程才能进入....依次类推 */ synchronized (this) { // 如果没有票 退出循环 if (counts <= 0) { break; } counts--; // 卖了一张票 num++; System.out.println(Thread.currentThread().getName() + "抢到了第" + num + "张票!剩余票数:" + counts); } } synchronized (this) { //当有线程进入一个synchronized代码块时,所有 synchronized代码块都会上锁,不能进入 } } /** * 模拟3个人同时抢票 */ public static void main(String[] args) { // 实例化线程类对象 SynchronizedSale sale = new SynchronizedSale(); Thread t1 = new Thread(sale, "小黑"); Thread t2 = new Thread(sale, "小白"); Thread t3 = new Thread(sale, "小红"); Thread t4 = new Thread(sale, "小粉"); Thread t5 = new Thread(sale, "小蓝"); System.out.println("开始抢票"); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); } }
/** * 售票的线程类 实现同步 */ public class SynchronizedSaleMethod implements Runnable { // 定义总票数 private int counts = 1000; // 定义出售票的下标 private int num = 0; // 定义一个标识 private boolean flag = false; @Override public void run() { while (!flag) { sale(); // 只要还有票 循环的调用卖票的方法 } } // 同步方法 public synchronized void sale() { // 如果没有票 退出循环 if (counts <= 0) { flag = true; return; } counts--; // 卖了一张票 num++; System.out.println(Thread.currentThread().getName() + "抢到了第" + num + "张票!剩余票数:" + counts); } /** * 模拟5个人同时抢票 */ public static void main(String[] args) { // 实例化线程类对象 SynchronizedSaleMethod sale = new SynchronizedSaleMethod(); Thread t1 = new Thread(sale, "小黑"); Thread t2 = new Thread(sale, "小白"); Thread t3 = new Thread(sale, "小红"); Thread t4 = new Thread(sale, "小粉"); Thread t5 = new Thread(sale, "小蓝"); System.out.println("开始抢票"); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); } }