黑马程序员_多线程2

来源:互联网 发布:淘宝上的逆战出售号 编辑:程序博客网 时间:2024/06/11 00:05

------- android培训java培训、期待与您交流! ----------

死锁:一旦产生程序就停在那儿不动了,没法继续执行下去。

死锁的出现:同步中嵌套同步
比如:同步函数中有同步代码块,同步代码块中有同步函数
面试的时候有可能让你写个死锁的例子:
下面给个线程死锁的例子:
class Test implements Runnable{private boolean flag;Test(boolean flag){this.flag = flag;}public void run(){if(flag){synchronized (MyLock.locka) {System.out.println("if locka");synchronized (MyLock.lockb) {System.out.println("if lockb");}}}else{synchronized (MyLock.lockb) {System.out.println("else locka");synchronized (MyLock.locka) {System.out.println("else lockb");}}}}}class MyLock{static Object locka = new Object();static Object lockb = new Object();}public class DeadLockTest {public static void main(String[] args) {Thread t1 =new Thread(new Test(true));Thread t2 =new Thread(new Test(false));t1.start();t2.start();}}


线程间通讯:其实就是多个线程在操作同一个资源,但是操作的动作不同
实现一个简单的小功能:一个往对象里面一直在加入东西一个一直往对象外面一直拿东西
只有存进去以后才能往外面拿,只有拿出了以后才能存
代码示例:

class Test implements Runnable{private boolean flag;Test(boolean flag){this.flag = flag;}public void run(){if(flag){synchronized (MyLock.locka) {System.out.println("if locka");synchronized (MyLock.lockb) {System.out.println("if lockb");}}}else{synchronized (MyLock.lockb) {System.out.println("else locka");synchronized (MyLock.locka) {System.out.println("else lockb");}}}}}class MyLock{static Object locka = new Object();static Object lockb = new Object();}public class DeadLockTest {public static void main(String[] args) {Thread t1 =new Thread(new Test(true));Thread t2 =new Thread(new Test(false));t1.start();t2.start();}}

唤醒全部线程的话可以用notifyAll();
wait(),notify(),notifyAll(),都使用在同步总,因为要对
持有监视器(锁)的线程操作,所以要使用在同步中,因为只有同步才具有锁。
为什么这些操作线程的方法要定义Object类中呢?
因为这些方法在操作同步中线程时,都必须要标识它们所操作线程只有的锁,
只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒。
不可以对不同锁中的线程进行唤醒
也就是说,等待和唤醒必须是同一个锁
而锁可以是任意对象,所以可以被任意对象调用的方法定义object类中
生产者消费者模式:


public class Test {public static void main(String[] args) {Resource r = new Resource();Producer pro = new Producer(r);Consumer con = new Consumer(r);Thread t1 = new Thread(pro);Thread t2 = new Thread(con);t1.start();t2.start();}}class Resource{private String name ;private int count =1;private boolean flag = false;public synchronized void set(String name ){if(flag)try {this.wait();} catch (Exception e) {}this.name = name +"---"+count++;System.out.println(Thread.currentThread().getName()+"......生产者......."+this.name);flag = true;this.notify();}public synchronized void out(){if(!flag)try {wait();} catch (Exception e) {}System.out.println(Thread.currentThread().getName()+".......消费者....."+this.name);flag = false;this.notify();}}class Producer implements Runnable{private Resource res; Producer(Resource res) {this.res = res;} public void run(){ while(true){ res.set("+商品“+"); } }}class Consumer implements Runnable{private Resource res; Consumer(Resource res) {this.res = res;} public void run(){ while(true){ res.set("+商品“+"); } } }


这个程序在线程大于2的时候会出现问题
if(flag)当出现超过两个以上的线程时,容易唤醒本方,引文
if只执行一次,所以需要换成while(flag),而while(flag)容易出现死锁
所以这时需要this.notifyAll()唤醒所有等待的线程。
Lock实现提供了比使用synchronized方法和语句可获得的更广泛的锁定操作。
Lock是1.5以后升级才出现的
Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,
Condition 替代了 Object 监视器方法的使用。
使用lock和condition写生产者消费者模式 
class Resource{private String name ;private int count =1;private boolean flag = false;private Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();public  void set(String name ) throws Exception{lock.lock();try {while(flag)condition .await();this.name = name +"---"+count++;System.out.println(Thread.currentThread().getName()+"......生产者......."+this.name);flag = true;}finally{lock.unlock();}}public synchronized void out(){lock.lock();try {while(!flag)condition.await();System.out.println(Thread.currentThread().getName()+".......消费者....."+this.name);flag = false;} finally{lock.unlock();}}class Producer implements Runnable{private Resource res; Producer(Resource res) {this.res = res;} public void run(){ while(true){ res.set("+商品“+"); } }}Lock使用的官方文档: Lock l = ...;      l.lock();     try {         // access the resource protected by this lock     } finally {         l.unlock();     }


如果需要定义只唤醒自己的,则可以定义多个condition
private Condition condition_pro = lock.newCondition();private Condition condition_con = lock.newCondition();    condition_pro .await();condition_con.signal();//唤醒对方的线程


线程的停止:stop方法已经过时,那么现在如何停止线程呢
只有一种方式,run方法结束,开启多线程运行,运行代码通常都是循环结构,
只要控制住循环,就可以让run方法结束,也就是线程结束。
特殊情况:当线程处于了冻结状态,就不会读取到标记,那么线程就不会结束。
当没有指定的方式让冻结的线程回复到运行状态时,这时需要对冻结进行清除
强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束
Thread类中提供了该方法叫:interrupt()可以让一个线程处于中断状态
Thread t2 = new Thread(t1);
t2.join();
t2抢夺线程的执行权,只有当t2这个线程运算完了以后主线程才能执行
join:当A线程执行到了B线程的.join()方法时,A就会等待,等
B线程执行完了以后才会执行A线程
join可以用来临时加入线程
setPriority()可以设置线程的优先级,主线程和其它线程默认的是5
优先级1、5、10最明显
MAX_PRIORITY(10)  MIN_PRIORITY(1)  NORN_PRIORITY(5)
yieId() 暂停当前正在执行的线程对象,并执行其他线程
原创粉丝点击