1.Thread类实现了Runnable接口。
2.自定义线程的方法1:
⒈ 定义类继承Thread类,⒉重写run() ⒊创建该线程对象,调用start()开启线程。
调用start()的作用:⒈开启线程 ⒉执行重写的run()。
发现每次执行的结果不一致:这是因为多个线程都获取了cpu的执行权利,但cpu再高速切换执行,随机执行某个进行,执行谁和执行时间由cpu来决定。
cpu做着高速的切换,从而达到看上去多个程序同时运行的效果。
3.为什么覆盖run():将自定的代码存储在run()中,让创建的线程去执行。
4.自定线程的方法2:
⒈定义类来实现Runnable接口⒉重写run()⒊创建该实现类对象,并将该对象当做实参传递给Thread的构造函数,⒋调用start()开启线程。
5.为什么要将Runnable接口的实现类当作实参传递给Thread类的构造函数?
因为自定的run()所属的对象是Runnable的实现类,所以要让线程知道自己执行哪个run(),调用Thread类的start()开启线程,并执行Runnable实现类重写的run()。
6.实现和继承的区别:
实现:避免了单继承的局限性,在定义线程时,建议使用这种方式。
两种方式创建的自定义线程对象中run()所处的位置不同。
继承:是对类共性功能的赋予。 实现:是对类进行一个功能扩展。
7.线程的一些方法:
getName():获取线程的名称,默认名称是thread i
setName():设置线程的名称,也可以通过线程的构造函数来设置。
Thread.currentThread():获取当前正在执行的线程对象的引用。
8.同步代码块:
synchronized(对象){需要同步执行的代码}:对象如同锁,持有锁的线程可以在同步中执行,没有持有锁的线程即使获得执行权也不能执行同步代码块中的代码。
同步的前提:⒈两个或以上线程⒉多个线程使用的是同一个锁,
好处:解决了多线程的安全问题。弊端:多个线程每次执行都需要判断锁,耗费资源。
9.同步的两种形式:
⒈同步代码块 ⒉同步函数(静态和非静态都可以)
10.若出现问题如何找问题:
⒈明确哪些代码是多线程运行的代码。
⒉明确共享资源
⒊明确多线程代码中哪些语句可以操作共享语句。
11.死锁:同步中嵌套同步,锁的位置颠倒。
12.等待唤醒机制:
sleep(); sleep(long l); 休眠。
⒈wait(); notify(); notifyAll(); 全用在同步中,因为需要监视器,对持有监视器的线程进行操作。
这些方法(这三个)全部定义在Object类中,因为这些方法在操作同步线程时,都必须要标识他们所操作的线程持有的锁,同一个被锁上的等待线程,只可以被同一个锁上的notify()唤醒。注:不可以对不同锁中的线程进行唤醒。
任意对象都是一个锁,所以被定义在Object中。
13.JDK1.5升级,将同步synchronized换成显示的lock操作:
Lock lock = new Lock();
lock.lock();//上锁
lock.unLock();//解锁
将Object中的wait notify notifyAll替换成了Condition对象,可以通过Lock来获取。
14.线程的启动只有一次,否则抛异常。
15. 创建线程对象开启线程---可运行-------运行-------死亡
- -
冻结,休眠
16.创建锁对象。
可以使用this关键字作为锁对象,也可以使用所在类的字节码文件对应的Class对象作为锁对象。⒈类名.class ⒉对象.getClass();
java中的每个对象都有一个内置锁,只有当对象具有同步方法代码时,内置锁才会起作用,当进行一个同步的非静态方法时,就会自动获得与类的当前实例相关的锁(即this),该类的代码就是正在执行的代码。
因为每个对象都只有一个锁,所以一个线程获取了这个锁,其他线程就不能获得这个锁了,知道线程释放锁,也就是说在释放锁之前,任何线程都不能执行同步代码。
注:释放锁指 持有锁的线程退出同步方法,此时其他线程可以执行该对象的同步方法。
17.线程的生命周期:⒈正常终止: 当run()执行完毕后,线程销毁。
⒉使用标记来停止线程。(在run中添加标记,让自身或其他线程来决定消亡时机。)
18.后台线程(守护线程):就是隐藏起来一直默默运行的线程,直到进程结束。
setDaemon(boolean b);//将某一线程标记为守护线程,必须在启动线程之前调用此方法。
特点:当所有的非后台线程结束时,程序也终止了,同时还会停止正在运行的守护线程,例如main线程就是非后台线程,将自定义创建的线程标记为守护线程,当main停止时,守护线程也会停止运行。
isDeamon();//测试该线程是否为守护线程。
19.join():当A线程执行到B线程的join()时,A线程会进入等待状态,当B线程执行完毕后,A线程才会继续执行。
20.静态同步函数的锁是:该方法所在类的字节码文件对象。
非静态同步函数的锁是:this
同步代码块:自己指定锁。
21.
⒈wait():告诉当前线程放弃执行权,并放弃锁进入阻塞状态,直到其他线程获得执行权,并持有了相同的锁并调用notify()或notifyAll()为止。
⒉notify():唤醒持有同一个锁中调用wait()的第一个线程。
⒊notifyAll():唤醒持有同一个锁中调用wait()的所有线程。
22.sleep()和wait()的区别:
sleep():释放资源,不释放锁,是Thread中的方法。
wait():释放资源,释放锁,是Object中的方法。