静态同步方法的锁对象: 类名.class ---> 字节码文件对象
Lock: 锁,jdk1.5版本
lock() 上锁
unLock() 解锁
—————————————————————————————
死锁: 是指两个或者两个以上的线程在执行的过程中,因争夺资源产生的一种互相等待现象
synchronized (A){
synchronized (B){
...
}
}
—————————————————————————————
等待唤醒机制: 图解
public final void wait() throws InterruptedException
public final void wait(long timeout) throws InterruptedException
public final void wait(long timeout, int nanos) throws InterruptedException
上面3个方法的作用是让当前线程对象等待,需要通过 notify()方法或 notifyAll()方法进行唤醒
当调用该方法后,会释放当前线程对象上的 锁对象, 同时,释放CPU执行权
Synchronzied (p) {
....
p.wait(); /将某个线程等待
...
}
public final void notify()
唤醒当前锁对象上 处于等待状态的线程
如果当前锁对象上 有多个线程处于等待状态,会随机唤醒其中的一个线程
public final void notifyAll()
唤醒当前锁对象上 处于等待状态的线程
如果当前锁对象上 有多个线程处于等待状态, 会唤醒所有处于等待状态的线程
—————————————————————————————
Java中使用ThreadGroup来表示线程组,它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制。
默认情况下,所有的线程都属于主线程组。
public final ThreadGroup getThreadGroup()
我们也可以给线程设置分组
Thread(ThreadGroup group, String name)
Thread(ThreadGroup group, Runnable target)
Thread(ThreadGroup group, Runnable target, String name)
—————————————————————————————
ThreadPool 线程池:
好处:
省去了频繁创建线程对象的操作
创建好的线程对象可以重复使用
JDK5新增了一个Executors工厂类来产生线程池,有如下几个方法
Executors类中方法:
public static ExecutorService newCachedThreadPool()
public static ExecutorService newFixedThreadPool(int nThreads)
public static ExecutorService newSingleThreadExecutor()
ExecutorService线程池类
Future> submit(Runnable task)
获取线程池中的某一个线程对象,并执行线程中的run()方法
获取线程池中的某一个线程对象,并执行线程中的call()方法
//获取线程池中的线程,调用Callable接口子类对象中的call()方法, 完成求和操作
//
// Future 结果对象
Future
//此 Future 的 get 方法所返回的结果类型
Integer sum = result.get();
使用线程池中线程对象的步骤:
创建线程池对象
创建Runnable实例对象
提交Runnable实例
关闭线程池
—————————————————————————————
匿名内部类方式使用多线程
new Thread(){代码…}.start();
new Thread(new Runnable(){代码…}).start();
new Thread(){
@Override
public void run() {
System.out.println("haha");
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("heihei");
}
}).start();
—————————————————————————————
Timer: 时钟类
public Timer()
public void schedule(TimerTask task, long delay)
当给定的延迟时间达到后,执行 时钟任务类中的代码
public void schedule(TimerTask task,long delay,long period)
当给定的延迟时间 delay 达到后,执行 时钟任务类中的代码
然后再等指定的时间 period 达到后,重复的执行 时钟任务类中的代码
TimerTask 时钟任务类
public abstract void run()
public boolean cancel()
—————————————————————————————
1, 多线程有几种实现方案,分别是哪几种?
a, 继承Thread类
b, 实现Runnable接口
c, 通过线程池,实现Callable接口
2, 同步有几种方式,分别是什么?
a,同步代码块
b,同步方法
静态同步方法
3, 启动一个线程是run()还是start()?它们的区别?
启动一个线程是start()
区别:
start: 启动线程,并调用线程中的run()方法
run : 执行该线程对象要执行的操作
4, sleep()和wait()方法的区别
sleep: 不释放锁对象, 释放CPU使用权
在休眠的时间内,不能唤醒
wait(): 释放锁对象, 释放CPU使用权
在等待的时间内,能唤醒
5, 为什么wait(),notify(),notifyAll()等方法都定义在Object类中
锁对象可以是任意类型的对象
6, 线程的生命周期图
看图
—————————————————————————————
单例设计思想
保证类在内存中只有一个对象
如何实现类在内存中只有一个对象呢?
构造私有
本身提供一个对象
通过公共的方法让外界访问
实现方式:
饿汉式 : 直接创建对象
线程安全的
懒汉式 : 当要用到对象的时候,再创建对象(延迟加载方式)
一个线程对象的时候,线程安全的
多个线程对象的时候,线程不安全, 可以同步机制处理
//保证类在内存中只有一个对象[饿汉式 : 直接创建对象]
public class Son {
//1, 构造方法私有化
private Son(){
}
//本身提供一个对象
private static Son s = new Son();
//通过公共的方法让外界访问
public static Son getInstance(){
return s;
}
}
//保证类在内存中只有一个对象[懒汉式 : 当要用到对象的时候,再创建对象(延迟加载方式)]
public class Girl {
//构造方法私有
private Girl(){
}
//创建本类对象的引用
private static Girl g = null;
//提供通过公共的方法让外界访问
//第一次访问该方法,创建对象
//之后再访问该方法,返回以前创建好的对象
public synchronized static Girl getInstance(){
//第一次访问该方法,创建对象
if (g == null) {
//t1,t2
g = new Girl();
}
//之后再访问该方法,返回以前创建好的对象
return g;
}
}