多线程-验证同步函数的锁
1 package multithread.test; 2 3 /* 4 * 同步函数使用的锁是this 5 * 6 * 同步函数和同步代码块的区别: 7 * 同步函数的锁是固定的this。 8 * 9 * 同步代码块的锁是任意的对象 10 * 11 * 建议使用同步代码块 12 */ 13 class Ticket implements Runnable {//extends Thread { 14 private /*static*/ int num = 100;//静态是可以的,根据实际看,有可能是这个线程负责这种100张,另一个线程时另一种票100张 15 Object obj = new Object(); 16 boolean flag = true; 17 public void run() /*throws 不处理就抛,但是实现接口覆盖的方法,接口没有声明过异常,只能catch不能声明*/{ 18 // Object obj = new Object();//每个线程开启都会创建一个对象,就会有不同锁,会出错 19 System.out.println("this:"+this); 20 if (flag) { 21 while(true) { 22 synchronized (this) { 23 if (num>0) { 24 try { 25 Thread.sleep(10);//sleep方法有个抛出 26 } catch (InterruptedException e) { 27 } 28 // 29 System.out.println(Thread.currentThread().getName()+"....sale...."+ num--); 30 } 31 } 32 33 } 34 }else { 35 while(true) { 36 this.show(); 37 } 38 } 39 40 } 41 public synchronized void show() { 42 if (num>0) { 43 try { 44 Thread.sleep(10);//sleep方法有个抛出 45 } catch (InterruptedException e) { 46 } 47 // 48 System.out.println(Thread.currentThread().getName()+"....function...."+ num--); 49 } 50 } 51 } 52 //会出现两个相同的票数,可能会出现0票,因为用了不同的锁,同步函数的锁和代码块的锁不一样,同步函数仅仅是函数代表了同步性,本身不带锁, 53 public class SynFunctionLockDemo { 54 55 public static void main(String[] args) { 56 // TODO Auto-generated method stub 57 Ticket t = new Ticket();//创建一个线程任务对象。 58 59 System.out.println("t:"+t); 60 Thread t1 = new Thread(t); 61 Thread t2 = new Thread(t); 62 // Thread t3 = new Thread(t); 63 // Thread t4 = new Thread(t); 64 65 t1.start(); 66 try { 67 Thread.sleep(10); 68 } catch (InterruptedException e) { 69 70 } 71 t.flag = false; 72 t2.start(); 73 // t3.start(); 74 // t4.start(); 75 } 76 77 }