线程的同步
《零基础学Java》
-
线程的同步
在单线程程序中,每次只能做一件事情,后面的事情需要等待第一件事情完成后才可以进行。为此,Java提供了线程同步机制来防止多线程编程中抢占资源的问题。
-
线程安全
在编写多线程程序时,应该考虑到线程安全问题。
模拟未考虑到线程安全问题的售票系统:
public class Demo5 implements Runnable { int unm = 10;// 售票池 总票数 public static void main(String[] args) { Demo5 demo5 = new Demo5(); Thread thread1 = new Thread(demo5, "1");// 一号售票机 Thread thread2 = new Thread(demo5, "2");// 二号售票机 Thread thread3 = new Thread(demo5, "3");// 三号售票机 Thread thread4 = new Thread(demo5, "4");// 四号售票机 thread1.start();// 开启线程 thread2.start(); thread3.start(); thread4.start(); } @Override public void run() { while (true) { if (unm > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("票数:" + unm--); } } } }
模拟未考虑到线程安全问题的售票系统 输出结果:
-
线程同步机制
同步块:
Java中提供了同步机制,可以有效的防止资源冲突。同步机制使用 synchronized关键字 使用该关键字的代码块称为同步块。
同步块 语法:
synchronized (Object){ }
同步块 实例:
public class Demo6 implements Runnable{ int unm = 10;// 售票池 总票数 public static void main(String[] args) { Demo6 demo6 = new Demo6(); Thread thread1 = new Thread(demo6, "a1");// 一号售票机 Thread thread2 = new Thread(demo6, "a2");// 二号售票机 Thread thread3 = new Thread(demo6, "a2");// 三号售票机 Thread thread4 = new Thread(demo6, "a4");// 四号售票机 thread1.start();// 开启线程 thread2.start(); thread3.start(); thread4.start(); } @Override public void run() { while (true) { synchronized (this){// 同步代码块,加锁对象为自身 if (unm > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("票数:" + unm--); } } } } }
同步块 实例输出结果:
同步方法:
同步方法就是被 synchronized关键字 修饰的方法。当某个对象调用了同步方法时,该对象的其他方法必须等待该同步方法执行完毕后才能被执行。必须将每个能访问共享资源的方法都修饰为synchronized,否则会出错。
同步方法 语法:
synchronized void name(){ }