黑马程序员_java学习日记_线程二
------- android培训、java培训、期待与您交流! ----------
?
1、线程间通讯;
?
?其实就是多个线程在操作同一个资源。
?
?但是操作的动作不同。
?
? 1)注意:我们想在不同的类中,获取某个类的同一个对象,我们可以通过不同类中创建构造函数。
?
??? 通过初始化构造函数,来获取想要类中的引用。因为在不同的类中的引用是都指向同一个对象的。这个是重点。
?
? 2)对于锁的问题。不同类中的锁,要变成同一把锁,我们可以采用类的字节码文件对象,
?
??? 因为类的字节码文件对象是不可能改变的,是唯一的。还可以使用共同的类资源的引用。
?
??? 因为不同的线程获取的资源类是同一个,这个也是重点。总之锁要唯一性。同一个锁才能用。
?
2、等待唤醒机制:
?
?? 下面的方法都必须用在同步里面:
?
?? 1)wait();本线程等待,其他线程可以执行。
?
?? 2)notify();唤醒其他线程。
?
?? 3)notifyAll();全部唤醒,唤醒线程池中的所有。
?
?????? 注意:上面的方法必须通过锁对象去调用;重点呀;
?
?? 注意:等待的线程都存在线程池当中。
?
3、等待唤醒机制的总结;
?
? wait();
?
? notify();? 注意:它一般会唤醒线程池中第一个处于冻结的线程。当有多个线程的时候,我们会使用notifyall().
?
? notifyAll();
?
? 都使用在同步中,因为他们都是对持有监视器(锁)的线程操作。
?
? 所以要使用他们,就要在同步中使用,因为只有同步才具有锁。
?
? 为什么这些操作方法要定义在object中呢?
?
? 因为这些方法在操作同步线程中时,都必须要表示它们所操作的线程只有锁,
?
? 只有同一个锁上的被等待的线程时,可以被同一个锁上的notify唤醒。
?
? 不可以对不同锁中的线程进行唤醒。
?
? 也就是说等待和唤醒必须是同一个锁。
?
? 而锁可以是任意对象,所以可以被任意对象调用方法定义在Object类中。
?
4、注意:
?
?? 判断标记位的时候,我们一般用while循环去判断,否则就会出现多生产出产品的问题。
?
?? 多个线程执行的时候,要唤醒对方线程,我们一般用notifyAll();否则会就出现相互等待状态。
?
5、总结:对于多个生产者和消费者。
?
?? 为什么要定义while判断标记。
?
?? 原因:让被唤醒的线程再一次判断标记。
?
?? 为什么定义notifyAll,
?
?? 因为需要唤醒对方线程。
?
?? 因为只用notify,容易出现只唤醒本方线程的情况,导致程序所有线程都等待。
?
6、jdk1.5中提供了多线程升级解决方案,
?
??? 将同步Synchronized替换成显示的Lock操作。
?
?? 将Object中的wait ,notify ,notifyAll,替换成了Condition对象。
?
?? 该对象可用Lock锁进行获取。
?
?? 该示例中,实现了本方法只唤醒对方操作。原因是可以创建多个Condition对象。
?
7、停止线程代码;
?
?? 如何停止线程呢?
?
?? 只有一种方法,run方法结束。
?
?? 开启多线程运行,运行的代码通常是循环结构,
?
?? 只要控制住循环,就可以让run方法结束,也就是线程结束。
?
?? 特殊情况:
?
?? run函数体被Synchronized修饰,并且里面有wait(),sleep()等方法时会出现冻结状态,无法用notify进行唤醒时,我们会用????? interrupt()进行中断请求;
?
?? run()方法里面有wait(),sleep();等都处于冻结状态时,我们会采用intterrup()方法来中断线程。
?
?? 当线程处于冻结状态。就不对读取到标记,那么线程就不会结束。
?
?? 当没有指定的方式让冻结的线程恢复到运行状态时,这时就需要对冻结进行清除,
?
?? 强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束。
?
?? Thread类提供该方法是interrupt();
?
8、后台线程(守护线程,用户线程):
?
?? 注意:我们看到的都是前台线程。所有的前台线程都结束后,后台线程会自动结束。
?
?? 守护线程必须在线程启动前完成。
?
?? t1.setDaemon(true);
?
?? t2.setDaemon(true);
?
?? 设置为守护线程的都是在其他线程结束后,它们会自动结束,不会让其处于冻结状态。
?
9、join();的用法;
?
?? join();是抢夺执行权。它先执行完了,其他的线程在执行。
?
?? join;当A线程执行了B线程的.join()方法时,A就会等待,等待B线程都执行完毕,A才会执行。
?
?? join可以用来临时加入线程执行。
?
10、yield是暂时释放执行权,放入共用代码块中,我们可以使不用的线程平均执行。都有执行的机会。
?
11、匿名内部类来写线程:
?
方法一:new Thread()??????????????????????????????????????????
?
?????? {
?
?????????? pubulic void run()
?
?????????? {
?
??????????????? for(int x= 0;x<100:x++)
?
??????????????? {输出语句}
?
??????????? }
?
??????? }.start();
?
方法二? Runnable r = new Runnable()??????????????????????????????????????????
?
????????? ???????????? {
?
??????????????? ???????????? pubulic void run()
?
????????????? ??? ??????????? {
?
?????????????????? ???????????? ?for(int x= 0;x<100:x++)
?
??????????????????? ?????????? {输出语句}
?
????????????? ??? ???????????? ?}
?
??????
?
??? ???????????? ?}
?
?????? ?? ????????new Thread(r).start();???
?