多线程安全问题。 当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的错误。 解决方法:对多条操作共享数据的语句,只能让一个线程都执行完;在执行过程中,其他线程不可以参与执行。 Java对于多线程的安全问题提供了专业的解决方式。就是同步代码块。 Synchronized(对象) { 需要被同步的代码; } 对象如同锁,持有锁的线程可以在同步中执行。 没有持有锁的线程即使获取CPU执行权,也近不去,因为没有获取到锁。 经典例子:火车上的卫生间。 同步的前提: 1, 至少有两个线程。 2, 必须是多个线程使用同一个锁。 必须保证同步中只有一个线程在运行。 好处:解决了多线程的安全问题。 弊端:多个线程需要判断锁,较为消耗资源。 同步有两种表现形式:同步函数和同步代码块。 同步函数使用的是哪一个锁呢? 函数需要被对象调用,那么函数都有一个所属对象的引用:就是this。所以同步函数使用的锁是this。 多窗口同时买票: class Ticket implements Runnable { private int tick=100; //Object obj =new Object(); boolean flag=true; public void run() { if(flag) { while(true) { synchronized(this) { if(tick >0) { System.out.println(Thread.currentThread().getName()+" code: "+tick--); } } } } else { while(true) show(); } }
public synchronized void show() { if(tick >0) { System.out.println(Thread.currentThread().getName()+" ...show... "+tick--); } } } class TicketDemo2//ThisLockDemo { public static void main(String[] args) { Ticket t =new Ticket(); Thread t1=new Thread (t);// Thread t2=new Thread (t);// t1.start(); t.flag=false; t2.start(); } } 当同步函数被静态修饰后,使用的锁是什么? 不是this,因为静态方法中不可以定义this。 静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象。
静态的同步方法,使用的锁是该方法所在类的字节码文件对象。类名.class。 |