Java多线程(一):

  1. 实现线程的两种方式TraditionalThread

继承Thread类,实现implements Runable接口

  2. Timer/TimerTask定时器使用(53) TraditionalTimerTest

题目:写一个Timer实现输出一个字符串,第一次间隔2s,第二次间隔4s,第三次间隔2s,交替进行。两种实现(使用一个Timer,使用两个Timer)。

注意:匿名内部类中不能定义static变量。

更好的开源框架学习:quartz

  3. 线程互斥技术(synchronized)(54TraditionalThreadSynchronized

类似银行转账问题

案例:分别启动两个线程安字母打印名字循环输出,使用synchronized实现互斥

注意:内部类中访问局部变量需加final

如果使用多个synchronized会出现死锁现象。

静态的方法锁“门栓”是当前类的class,普通方法的“门栓”是this

要实现互斥,synchronized所使用的“门栓”必须相同。

  4. 线程同步通信技术(waitnotify)(54TraditionalThreadCommunication

自动登录案例,加密和解密cookie的实现,好处高内聚低耦合。

面试题:子线程循环10次,主线程循环5次,两者交替运行50次。

  推荐写法:

   synchronized (obj) {

         while (<condition does not hold>)

             obj.wait();

         ... // Perform action appropriate to condition

   }

关于线程同步的代码是写在共享变量中的不要写在线程中使用。

  5. 线程范围内共享变量(ThreadLocalThreadScopeShareData57

实现:Map<Thread,Object> get取值的使用从map中取得数据。分别得到的数据是属于这个线程的。保证了在该线程中操作的对象不会干扰别的线程。

  1. 多个线程访问共享对象和数据的方式
  2. 如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有的数据就是共享数据.例如,卖票系统
  3. 如果每个线程执行的代码不同,这时需要用不同的Runnable对象,有如下两种方式来实现这些Runnable对象之间的数据共享

a) 将共享数据封装在另外一个对象中,然后将这个对象逐一传递给各个Runnable对象。每个线程对共享数据的操作方法也分配到那个对象上面去完成,这样容易实现针对该数据进行的各个操作的互斥和通信。(传入runnable)

b) 将这些Runnable对象作为某一个class中的内部类,共享数据作为这个外部类中的成员变量,每个线程对共享数据的操作方法也分配给外部类,以便实现对共享数据进行的各个操作的互斥和通信,作为内部类的各个Runnable对象调用外部class的这些方法. (runnable去共同方法去取)

c) 前两种方式组合:将共享数据封装在另一个对象中,每个线程对共享数据的操作方法也分配到那个对象身上去完成,对象作为这个外部类中的成员变量或方法中的局部变量,每个线程的Runnable对象作为外部类中的成员内部类或局部内部类。

总结:要同步互斥的几段代码最好分别放在几个独立的方法中,这些方法再放在同一个类中,这样比较容易实现他们之间的线程同步互斥和通信。

最极端且简单的方式,就是在任何一个class中或者接口中定义public static变量,这个变量将被所有线程共享。

总结中有部分代码没有上传,请大家可以在评论中给出答案哈!

原文地址:https://www.cnblogs.com/hnxubin/p/4381536.html