从买票问题开始
package com.google.thread; /** * 买票示例下的安全问题。 * 出现的原因 * * 解决思路 * * 同步代码块。 * * 火车上的卫生间。 */ class Ticker implements Runnable{ public int num = 100; Object obj=new Object(); public void run() { while (true) { //同步代码块 if (num > 0) { try { Thread.sleep(10); System.out.println(Thread.currentThread().getName() + "...." + num--); } catch (InterruptedException e) { e.printStackTrace(); } } } } } /* 线程安全问题。会卖出0号票。 Thread-3....-1 Thread-1....2 Thread-2....0 */ public class ThreadDemo extends Thread { public static void main(String[] args) { Ticker t = new Ticker(); Thread t1=new Thread(t);//创建线程 Thread t2=new Thread(t); Thread t3=new Thread(t); Thread t4=new Thread(t); t1.start();//开启线程 t2.start(); t3.start(); t4.start(); } }
线程安全问题。
会卖出0号票。
多个线程在操作共享的数据。
操作共享数据的线程代码有多条。
当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算。就会导致线程安全问题的产生。
解决方法
就是讲多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程是不可以参与运算的。
必须要在当前线程吧这些代码都执行完毕后,其他线程才可以参与运算。
同步代码块
在java中可以用同步代码块来解决这个问题。
同步代码块的格式
synchronized(对象){
需要被同步的代码;
}
同步的好处:解决了线程安全性问题。
同步的弊端:相对降低了资源,因为同步外的线程都需要判断同步锁。
同步后的代码
1 package com.google.thread; 2 /** 3 * 买票示例下的安全问题。 4 * 出现的原因 5 * 6 * 解决思路 7 * 8 * 同步代码块。 9 * 10 * 火车上的卫生间。 11 */ 12 class Ticker implements Runnable{ 13 public int num = 100; 14 Object obj=new Object(); 15 public void run() { 16 while (true) { 17 //同步代码块 18 synchronized (obj) { 19 if (num > 0) { 20 try { 21 Thread.sleep(10); 22 System.out.println(Thread.currentThread().getName() + "...." + num--); 23 } catch (InterruptedException e) { 24 e.printStackTrace(); 25 } 26 27 } 28 } 29 } 30 } 31 } 32 /* 33 线程安全问题。会卖出0号票。 34 Thread-3....-1 35 Thread-1....2 36 Thread-2....0 37 */ 38 public class ThreadDemo extends Thread { 39 public static void main(String[] args) { 40 Ticker t = new Ticker(); 41 42 Thread t1=new Thread(t);//创建线程 43 Thread t2=new Thread(t); 44 Thread t3=new Thread(t); 45 Thread t4=new Thread(t); 46 47 t1.start();//开启线程 48 t2.start(); 49 t3.start(); 50 t4.start(); 51 } 52 }