java多线程问题
1、多线程:一个进程有多个线程。
进程:指一块内存中运行的应用程序。
多线程:多个线程同时运行,但是这只是用户但感觉,例如同复制10个500M的文件到U盘,用户会看到10个文件的复制进度都在增加,但其实实际就是"多个线程快速切换",快到你分辨不出。
2、java中的线程
启动线程请使用start(),不要直接使用run()。
①Java.lang.Thread类的一个实例
Ⅰ、继承Thread类
父类引用指向子类对象
Ⅱ、实现Runnable接口
将MyRunnable对象传递到Thread中
Ⅲ、通过 Callable 和 Future 创建线程(较少提及使用这种方式)
②线程的执行
线程主要分为2种:用户线程和守护线程。
3、线程的5种状态
新建 --->就绪 ---> 运行 ---> 阻塞 --->死亡
sleep()方法必须要传入时间。。。这里还有个方法,this.yield()。当前线程会让出资源但是自己不会进入阻塞,而是进入就绪,依然可以和其它线程争抢。
- NEW 新建状态,线程创建且没有执行start方法时的状态
- RUNNABLE 可运行状态,线程已经启动,但是等待相应的资源(比如IO或者时间片切换)才能开始执行
- BLOCKED 阻塞状态,当遇到synchronized或者lock且没有取得相应的锁,就会进入这个状态
- WAITING 等待状态,当调用Object.wait或者Thread.join()且没有设置时间,在或者LockSupport.park时,都会进入等待状态。
- TIMED_WAITING 计时等待,当调用Thread.sleep()或者Object.wait(xx)或者Thread.join(xx)或者LockSupport.parkNanos或者LockSupport.partUntil时,进入该状态
- TERMINATED 终止状态,线程中断或者运行结束的状态
4、在共享同一资源的情况下:强烈建议使用Runnable.
1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
4):线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread的类
5、线程的常用方法
sleep(): 强迫一个线程睡眠N毫秒。
isAlive(): 判断一个线程是否存活。
join(): 等待线程终止。
activeCount(): 程序中活跃的线程数。
enumerate(): 枚举程序中的线程。
currentThread(): 得到当前线程。
isDaemon(): 一个线程是否为守护线程。
setDaemon(): 设置一个线程为守护线程。(用户线程和守护线程的区别在于,是否等待主线程依赖于主线程结束而结束)
setName(): 为线程设置一个名称。
wait(): 强迫一个线程等待。
notify(): 通知一个线程继续运行。
setPriority(): 设置一个线程的优先级。
6、同步代码块:synchronized{}
同步方法:@Synchronized/synchronized void test(){}
非静态方法 锁 this
静态方法 锁 当前字节码
建议加同步锁时,让锁的范围小一点,让其他线程获取资源时减少时间。
7、 适配器设计模式(掌握)
什么是适配器??????
在使用监听器的时候, 需要定义一个类事件监听器接口.
通常接口中有多个方法, 而程序中不一定所有的都用到, 但又必须重写, 这很繁琐.
适配器简化了这些操作, 我们定义监听器时只要继承适配器, 然后重写需要的方法即可.
适配器原理??????
适配器就是一个类, 实现了监听器接口, 所有抽象方法都重写了, 但是方法全是空的.
适配器类需要定义成抽象的,因为创建该类对象,调用空方法是没有意义的
目的就是为了简化程序员的操作, 定义监听器时继承适配器, 只重写需要的方法就可以了
8、生产者/消费者模式