《JAVA网络编程》阅读笔记(四)

1、运行线程:

         要让线程进行一些操作,可以对Thread类派生子类,覆盖其run()方法;或者实现Runnable接口,将Runnable对象传递给Thread构造函数。

     ①派生Thread的子类:只覆盖run()。

               

     ②实现Runnable接口:将希望线程执行的任务编写为Runnable接口的实例。这个接口声明了run()方法,这与Thread类完全一样。


                 

调用的区别:

                  



2、返回线程中的信息:单线程程序里,start()只是调用同一线程内的run()方法。start()开始的计算可能会在main()方法运行到调用函数之前结束,也可能不会。

      竞争条件:程序是否得到正确的运行结果,取决于很多因素,包括程序生成了多少线程,系统的CPU和磁盘的相对速度,以及Java虚拟机为不同线程分配时间所用的算法。



      轮询:让获取方法在结果字段设置之前返回一个标志值(或者可能抛出一个异常)。然后主线程定时询问获取方法,看是否返回了标志之外的值。



3、同步:

 线程:犹如读书馆的借阅者,从资源的中心池中借阅,通过共享内存、文件句柄、socket和其他资源,      使得程序更高效。只要两个线程不同时使用相同的资源,多线程的程             序就比多进程高效得多。(      多进程要为各个资源保存自己的副本)若两个线程同时访问相同的资源,其中一个就必须等待另      一个结束。
同步块:java为对象指定独占的方法时synchronized关键词。位指明这五行代码应当一起执行,要把它        们包围在对System.out对象同步的synchronized块中。(只要是多线            程共享资源,都必须考虑        同步,java中,所有资源都用某个类的实例对象表示,只有在两个线程都拥有相同对象的引用时,同步才成为问题)
同步的替代方法:1、在任何可能的情况下,使用局部变量代替字段。局部变量没有同步问题。
                                3、将非线程安全的类用作线程安全的类的一个私有字段


4、死锁:同步可能会导致死锁。当两个线程需要独立的相同的资源集时,而每个线程都锁定了这些资源的不同子集,就会发生死锁。如果两个线程都不愿意放弃已经拥有的资源,就会进入无限的停止。

                 防止死锁最重要的技术是避免不必要的同步(同步应该是避免线程安全的最后一种手段,若确实需要同步,要保持同步块尽可能小,尽量不要一次同步多个对象;若果多个对象需要操作相同的共享资源集,要确保以相同的顺序请求这些资源)。


5、线程调度:


      优先级:每个线程都有优先级,以1-10的整数指定(10 的优先级最高,默认优先级为5)。eg:public static final int MIN_PRIORITY=1;线程的优先级可以使用setPriority()方法来改变。

      抢占:每个虚拟机都有一个线程调度器,确定在任何时刻运行那个线程。有两种线程调度器:抢占式和协作式。

       抢占式线程调度器确定线程何时公平地享用CPU时间,然后暂停此线程,将CPU控制权交给另外的线程。

       协作式线程调度器会在将CPU控制权交给其他线程前,等待运行中的线程自己暂停,容易陷入饥饿(一个高优先级的非写作线程会独占整个CPU)。

     阻塞:在任何时候线程必须停下来等待它没有的资源时,就会发生阻塞。要让网络程序汇总的线程主动放弃CPU控制权,对此最常见的方式是在I/O时阻塞。线程也会在进行同步方法或代码块时阻塞,如果此线程不拥有被同步对象的锁,而其他线程拥有这个锁,那么这个线程就会暂停,直到锁被释放。阻塞于I/O和阻塞于锁,都不会释放任何线程已经拥有的锁。

      放弃:线程放弃控制权的第二种方式是显示放弃。线程可以通过Thread.yiedl()静态方法来完成放弃。

      休眠:休眠是更有力的放弃形式,进入休眠模式还拥有它获得的所有锁。因此,其他需要相同锁的线程会阻塞,及时CPU可用。所以要尽量避免在同步方法或块内让线程休眠。

       连接线程:一个线程需要另一个线程的结果。第一种方法:无线等待被连接的线程结束。第二种方法:等待指定的一段时间,然后会继续执行 ,即使被连接的线程还没有结束。

       等待一个对象:线程可以等待一个它锁定的对象。在等待时,它会释放此对象的锁并暂停,直到它得到其他线程的通知。另一个线程以某种方法修改了此对象,通知等待此对象的这个线程,然后继续执行。等待用于暂停执行,直到一个对象或资源达到某种状态。连接则用于暂停执行,直到一个线程结束。它将在下面三件事发生之前保持休眠:时间到期、线程被中断(其他线程调用该线程的interrupt()方法)以及对象得到通知(其他线程调用线程锁等待对象的motify()或notifyAll()方法会唤醒每一个等待指定对象的线程,就会发生通知,必须在线程所等待的对象上调用,而不是一般在Thread本身上调用)。

     基于优先级的抢占:高优先级先运行。

     结束:线程要以系统的方法放弃CPU控制权,最后一种方法时结束。当run()方法返回时,线程将销毁,其余线程就可以接管CPU。


6、线程池:把所有需要完成的任务放在队列或其他数据结构中,让每个线程在完成前面的任务后,再从对列中获取新的任务。

       引入原因:向程序添加多个线程会极大地提升性能,尤其是I/O受限的程序,线程有自己的开销,启动和销毁一个线程会耗费虚拟机的大量工作;回收垃圾也是很重的负担;更为重要的是在运行中线程之间切换意味着开销。线程一旦停止就不能重启。

       实现方法:1、在第一次创建池时分配固定数量的线程。每个线程都在池中等待。当向池添加一项任务时,所有等待的线程都会得到通知。当一个线程结束其分配的任务时,它再回到池中获取新的任务,若无,则继续等待;2、将线程本身放入池中,让主程序从池中取出线程,为其分配任务。如果必须要完成一项任务,而池中没有(可用的)线程时,主程序就生产一个新的线程。每个程序结束后都会返回到池中。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值