文章目录
  1. 1. Java多线程

Java多线程

  1. 要用到的共同数据(包括同步锁)或共同算法的苦干个方法应该写在同一个类里面,这种设计正好体现出高内聚和程序的健壮性,互斥同步的代码不要放到线程中,而应该放在资源类方法中。以后这个类要被其它线程调用,自然就同步了,而不需要其它的多加处理。
  2. ThreadLocal用于实现线程内的数据共享,即对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,而在另外线程中运行时又共享另外一份数据。每个线程调用全局ThreadLocal 对象的set方法,就相当于往其内部增加一条记录,key分别是各自的线程号,value是各自的set方法传进去的值,在线程结束时可以调用ThreadLocal.clear()方法,这样会更快释放内存,不调用也可以,因为线程结束后也可以自动释放相关的ThreadLocal变量。一个ThreadLocal代表一个对象,其中只能放一个数据,你有两个变量共享,则要定义两个ThreadLocal对象,如果有n个变量要线程共享,则把这几个变量定义成一个类,然后放这个类对象到ThreadLocal里
  3. 多个线程访问共享对象和数据的方式
    1. 如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,如卖票系统就可以这么做
    2. 如果每个线程执行的代码不同,这时候需要用不同的Runnable对象,有如下两种方式来实现这些Runnable对象之间的数据共享:
      1. 将共享数据封装在另外一个对象中,然后将这个对象逐一传递给各个Runnable对象。每个线程对共享数据的操作方法也分配到那个对象身上去完成,这样容易实现针对该数据进行的各个操作的互斥和通信
      2. 将这些Runnable对象作为某一个类中的内部类,共享数据作为这个外部类中的成员变量,每个线程对共享数据的操作方法也分配给外部类,以便实现对共享数据进行的各个操作的互斥和通信,作为内部类的各个Runnable对象调用外部类的这些方法
      3. 上面两种方法的组合:将共享数据封装在另外一个对象中,每个线程对共享数据的操作方法也分配到那个对象身上完成,对象作为这个外部类中的成员变量或方法中的局部变量,每个线程的Runnable对象作为作为外部类中的成员内部类或局部内部类
      4. 总之,要同步互斥的几段代码最好是分别放在几个独立的方法中,这些方法再放在同一个类中,这些比较容易实现它们之间的同步互斥和通信。
  4. 了解java.util.concurrent.atomic包,查看atomic包文档页下面的介绍,可以对基本数据,对数组中的基本数据,对类中的基本数据等进行操作
  5. Lock&Condition实现线程同步通信
    Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象。两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象。锁是上在代表要操作的资源的类的内部方法中,而不是线程代码中。

  6. 读写锁,分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可。如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁,如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁

  7. Condition的功能类似在传统线程技术中的Object.wait()和Object.notify()的功能。在等待Condition时,允许发生“虚假唤醒”,这通常作为对基础平台语义的让步。对于大多数应用程序,这带来的实际影响很小,因为Condition应该总是在一个循环中被等待,并测试正被等待的状态声明。某个实现可以随意移除可能的虚假唤醒,但应用程序员总是假定这些虚假唤醒可能发生,因此总是在一个循环中等待。在编程中一般在循环中放等待方法
  8. Semaphore可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数,如实现一个文件允许的并发访问数。 Semaphore实现的功能类似于厕所有5个坑,假如有十个人要上厕所,那么同时只能有5个人能够占用,当5个人中的任何一个人让开后,其中在等待的另外5个人中又有一个可以占用了。
  9. CyclicBarrier 表示大家彼此等待,大家集合好后才开始出发,分散活动后以在指定地点集合碰面,这就是好比整个公司的人员利用周末时间集体郊游一样,先各自从家出发到公司集合后,再同时出发到公园游玩,在指定地点集合后再同时开始吃饭
  10. CountDownLatch 犹如倒计时计数器,调用CountDownLatch对象的countDown方法就将计数器减1,当计数到达0时,则所有等待者或单个等待者开始执行。可以实现一个人(也可以是多个人)等待其他所有人都来通知他,可以实现一个人通知多个人的效果,类似裁判一声口令,运动员同时开始奔跑,或者所有运动员都跑到终点后裁判才可以公布结果,用这个功能做百米赛跑游戏程序不错。
文章目录
  1. 1. Java多线程