/* 解决多生产多消费的效率问题。 使用了JDK1.5 java.util.concurrent.locks包中的对象。 Lock接口:它的出现比synchronized有更多的操作。 lock():获取锁。 unlock():释放锁。 同步代码块或者同步函数的锁操作是隐式的。 JDK1.5 Lock接口,按照面向对象的思想,将锁单独封装成了一个对象。 并提供了对锁的显示操作。 Lock接口就是同步的替代。 1,将线程中的同步更换为Lock接口的形式。 替换完运行失败了。因为wait没有了同步区域,没有了所属的同步锁。 同步升级了。其中锁已经不是在任意对象,而是Lock类型的对象。 那么和任意对象绑定的监视器方法,是不是也升级了,有了专门和Lock类型锁的绑定的监视器方法呢? 查阅api。Condition接口替代了Object中的监视器方法。 以前监视器方法封装到每一个对象中。 现在将监视器方法封装到了Condition对象中。 方法名为:await signal signalAll 监视器对象Condition如何和Lock绑定呢? 可以通过Lock接口的newCondition()方法完成。 但是,问题依据,一样唤醒了本方。效率仍旧低! */ import java.util.concurrent.locks.*; //描述资源。 class Res { private String name; private int count = 1; //创建新Lock。 private Lock lock = new ReentrantLock(); //创建和Lock绑定的监视器对象。创建两个。 //生产者监视器。 private Condition producer_con = lock.newCondition(); //消费者监视器 private Condition consumer_con = lock.newCondition(); //定义标记。 private boolean flag; //提供了给商品赋值的方法。 public void set(String name)// { //获取锁。 lock.lock(); try{ while(flag)//判断标记为true,执行wait。等待。为false。就生产。 try{producer_con.await();}catch(InterruptedException e){}//t0(等) t1(等) this.name = name + "--" + count;//面包1 ,面包2 面包3 count++;//2 3 4 System.out.println(Thread.currentThread().getName()+"...生产者....."+this.name);//t0 面包1、 t0 面包2 t1 ,面包3 //生成完毕,将标记改为true。 flag = true; //生产完毕,应该唤醒一个消费者来消费。 consumer_con.signal(); }finally{ //释放锁。 lock.unlock(); } } //提供一个获取商品的方法。 public void get()// { lock.lock(); try{ while(!flag) try{consumer_con.await();}catch(InterruptedException e){}//t2(等) t3(等) System.out.println(Thread.currentThread().getName()+".......消费者....."+this.name);//t2 面包1. //将标记改为false。 flag = false; //消费完后,应该唤醒生产者一个。 producer_con.signal(); }finally{ lock.unlock(); } } } //生成者。 class Producer implements Runnable { private Res r; Producer(Res r) { this.r = r; } public void run() { while(true) r.set("面包"); } } //消费者 class Consumer implements Runnable { private Res r; Consumer(Res r) { this.r = r; } public void run() { while(true) r.get(); } } class NewProducerConsumerDemo { public static void main(String[] args) { //1,创建资源。 Res r = new Res(); //2,创建两个任务。 Producer pro = new Producer(r); Consumer con = new Consumer(r); //3,创建线程。 Thread t0 = new Thread(pro); Thread t1 = new Thread(pro); Thread t2 = new Thread(con); Thread t3 = new Thread(con); t0.start(); t1.start(); t2.start(); t3.start(); } }
class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }
wait()和sleep()的区别。 相同:可以让线程处于冻结状态。 不同点: 1,wait()可以指定时间,也可以不指定。 sleep().必须指定时间。 2,wait();释放cpu资源,释放锁。 sleep():释放cpu资源,不释放锁。 synchronized(obj) { obj.wait();//t0,t1,t2 code....; } synchronized(obj) { obj.notifyAll();//t3 } class { public static void main(String[] args) { System.out.println("Hello World!"); } }
/* 异常会提示发生在哪个线程上。 异常会结束线程任务,也就是可以结束所在线程。 */ class Demo implements Runnable { public void run() { System.out.println(4/0); } } class ThreadExceptionDemo { public static void main(String[] args) throws Exception { new Thread(new Demo()).start(); Thread.sleep(10); int[] arr = new int[3]; System.out.println(arr[2]); System.out.println("over"); } }
/* 如何停止线程? 原理:让run方法结束。 线程任务通常都有循环。因为开启线程就是为了执行需要一些时间的代码。 只要控制住循环,就可以结束run方法,就可以停止线程。 控制循环弄个标记即可。定义变量 */ class StopThread implements Runnable { private boolean flag = true; public synchronized void run() { while(flag) { try { wait();//t1 t2 } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName()+"............"+e.toString()); flag = false; } System.out.println(Thread.currentThread().getName()+"....hello"); } } public void changeFlag() { flag = false; } } class StopThreadDemo { public static void main(String[] args) { StopThread st = new StopThread(); Thread t1 = new Thread(st); Thread t2 = new Thread(st); t1.start(); t2.setDaemon(true);//将t2标记为后台线程。 t2.start(); for(int x=1; x<=50; x++) { if(x==40){ t1.interrupt();//将t1中断。 // t2.interrupt();//将t2中断。 // st.changeFlag(); } System.out.println("main...."+x); } System.out.println("over"); } }
class Demo implements Runnable { public void run() { for(int x=1; x<=40; x++) { System.out.println(Thread.currentThread().toString()+"......"+x); Thread.yield(); } } } class JoinDemo { public static void main(String[] args)throws InterruptedException { Demo d = new Demo(); Thread t1 = new Thread(d); Thread t2 = new Thread(d); t1.start(); t2.start(); // t1.join();//等待该线程终止。 t1.setPriority(Thread.MAX_PRIORITY); for(int x=1; x<=40; x++) { System.out.println(Thread.currentThread().toString()+"...."+x); } } }