public class Tickets implements Runnable{ private int ticket = 100; public void run(){ while(true){ if(ticket > 0){ System.out.println(Thread.currentThread().getName() + "出售票" + ticket--); } } } } pubilc static void main(String[] args){ Tickets ts = new Ticket(); Thread t0 = new Thread(ts); Thread t1 = new Thread(ts); Thread t2 = new Thread(ts); t0.start(); t1.start(); t2.start(); }
同步代码块解决线程问题:synchronized(Object obj){线程要操做的代码块}
java
private Object obj = new Object(); public void run(){ while(true){ synchronized(obj){ if(ticket > 0){ System.out.println(Thread.currentThread().getName() + "出售票" + ticket--); } } } }
同步对象:
任意对象,对象监听器多线程
没有锁的线程不能执行只能等待,碰见同步代码块,并发
private int ticket = 100; public void run(){ while(true){ pay(); } } } public static synchronized void pay(){ if(ticket > 0){] System.out.println(Thread.currentThread().getName() + "出售票" + ticket--); } //在同步方法中,对象锁是this。可是在静态方法中,对象锁不是this,this属于对象,优先于static,是本类本身.class
在线程中,只有出了同步代码块才会释放对象锁,可是要是出现了异常就不会释放了。因此在jdk5之后就使用Lock接口
this
public void lock() public void unlock()
锁的嵌套
出现了互锁线程
public class lockA{ public static final LockA lockA = new LockA(); private LockA(){ } } public class lockB{ public static final LockB lockB = new LockB(); private LockB(){ } } public class DeadLock implements Runnable{ private int i = 0; public void run(){ while(ture){ if(i%2 == 0){ //先进入A同步,在进入B同步 synchronized(LockA.locka){ System.out.println("if...locka"); synchronized(LockB.lockb){ System.out.println("else...lockb"); } } }else{ synchronized(LockB.lockb){ System.out.println("if...lockb"); synchronized(LockA.locka){ System.out.println("else...locka"); } } } } } }
多个线程操做同一个数据,可是操做的动做可能并不相同,经过必定的手段将各个线程有效的利用,既--等待唤醒机制code
public void wait()释放正在执行的线程的执行权,放到存储池对象
public void notify()唤醒在线程池中wait()的线程,一次唤醒一个,并且是任意的。接口
public void notifyAll(),唤醒在线程池中全部的wait()线程唤醒get
[x] 线程之间是否是全部的数据都锁上了同步
[x] 是否是用的同一个锁
public class Resource{ public String name; public String sex; public boolean flag;//唤醒标识 public Resource(String name,String sex){ this.name = name; } } public class InputThread implements Runnable{ private Resource r = null; public InputThread(Resource r){ this.r = r; } public void run(){ int i = 0; while(true){ synchronized(r){ if(r.flag){ try{ //必须是锁对象调用 r.wait(); }catch(Exception ex){ System.out.println(ex.getMessage()); } } if(i%2 == 0){ r.name = "张三"; r.sex = "男"; }else{ r.name = "lisi"; r.sex = "nv"; } i++; //执行完成,将标识修改,并唤醒对方。 r.flag = true; r.notify(); } } } } public class OutputThread{ private Resource r = null; public void run(){ //使用同一个对象锁 synchronized(r){ while(true){ if(r.flag){ try{ //必须是锁对象调用 r.wait(); }catch(Exception ex){ System.out.println(ex.getMessage()); } System.out.println(r.name); //执行完成,将标识修改,并唤醒对方。 r.flag = false; r.notify(); } } } public OutputThread(Resource r){ this.r = r; } } public class ThreadDemo{ public static void main(String[] args){ Resource r = new Resource(); InputThread int = new InputThread(r); OutputThread outt = new OutputThread(r); Thread in = new Thread(in); Thread out = new Thread(out); } }
对于线程来讲,要同步必须操做同一个锁对象
才能够,若是是使用各自来作本身的线程唤醒对象就不能实现同一个锁对象
,而且对于实现类来讲,调用者是谁?
==全部的线程的等待唤醒必须是锁对象调用,调用者是谁?任何方法都须要被调用,本类线程类是没有wait方法的,只有调用父类的super(),可是父类也没有这个方法,调用这个的锁对象是谁就由谁来调用,因此,同步的等待唤醒方法都是Object类的方法==