多线程--简单的卖票例子--基础
package com.lm.multest; /* * 通过分析,发现,打印出0,-1,-2等错票。 * 多线程的运行出现了安全问题。 * * 分析: * 问题的原因: * 当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完 * 另一个线程参与进来执行。导致共享数据错误。 * * 解决办法: * 对多条操作共享数据的语句,只能让一个线程执行完,在执行过程中,其他线程不可以参与执行。 * * Java对于多线程的安全问题提供了专业的解决的方式。 * * 就是同步代码块。 * * synchronized(对象) * { * 需要被同步的代码(那些语句在操作共享数据) * } * 对象如同锁。持有锁的线程可以在同步中执行。 * 没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。 * * 火车上的卫生间---经典例子。 * * * 同步的前提: * 1、必须要有两个或者两个以上的线程。 * 2、必须是多个线程使用同一个锁。 * * 必须保证同步中只能有一个线程在运行。 * * 好处:解决了多线程的安全问题。 * 弊端:多个线程都需要判断锁,教为消耗资源。 * * 同步函数用的是哪一个锁呢? * 函数需要被对象调用。那么函数都有一个所属对象引用。就是this。 * 所以同步函数使用的锁是this。 * * */ class Ticket implements Runnable{ private int num = 100; Object obj = new Object(); boolean flag = true; @Override public void run() { if(flag){ while(true){ synchronized(this){ //判断锁,会消耗资源,同一个锁this if(num>0){ System.out.println(Thread.currentThread().getName()+" "+num--); } } } }else{ while(true) show(); } } private synchronized void show(){ if(num>0){ System.out.println(Thread.currentThread().getName()+" "+num--); } } } public class MulOne { public static void main(String[] args) { Ticket t = new Ticket(); Thread a = new Thread(t); Thread b = new Thread(t); a.start(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } t.flag = false; b.start(); } }