1)线程的实现有两种方式,第一种方式是继承Thread类,然后重写run方法;第二种是实现Runable接口,然后实现其run方法。
2)当使用第二种方式来生成线程对象时,我们需要实现Runnable接口的run方法,然后使用newThread(new MyThread())来生成线程对象,这时的线程对象的run方法就会调用MyThread类的run方法。
3)实现Runnable接口和继承Thread类的区别:
a)实现Runnable接口避免了单继承的局限性。
b)通过继承Thread类来获得当前线程对象,直接使用this即可;但通过实现Runnable接口来获得当前线程对象,则必须使用Thread.currentThread()方法。
4)线程都有自己的默认名称:Thread-编号,编号从0开始。
5)调用线程对象的start()方法之后,该线程立即进入就绪状态—就绪状态相当于“等待执行”,但该线程并未真正进入运行状态。如果希望调用子线程的start()方法后子线程立即开始执行,可以使用Thread.sleep(1)来让当前运行的线程(主线程)睡眠1毫秒。
6)多线程同步问题:当多条语句在操作同一个线程共享数据时,一个线程的多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行。导致共享数据的错误。
7)同步的前提:
a)必须要有两个或者两个以上的线程。
b) 必须是多个线程使用同一个锁。
必须保证同步中只能有一个线程在运行。
8)synchronized块写法:
synchronized(object){
}
表示线程在执行的时候会对object对象上锁。
9)同步方法:就是用synchronized关键字来修饰某个方法。对于同步方法而言,无需显示指定同步锁,默认的锁是this,也就是该对象本身。
10)如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到了某个synchronized方法,那么在该方法没有执行完毕前,其他线程是无法访问该对象的任何synchronized方法的。
11)如果某个synchronized方法是static的,那么当线程访问该方法时,它锁的并不是synchronized方法所在的对象,而是synchronized方法所在的对象所对应的Class对象,因为Java中无论一个类有多少个对象,这些对象会对应唯一一个Class对象。
12)单例设计模式懒汉式的特点在于延时加载,但是可能出现线程同步问题。
懒汉式优化:
classSingleton{
private static Singleton s=null;
private Singleton();
public static Singleton getInstance(){
if(s==null){
synchronized(Singleton.class){
if(s==null){
s=new Singleton();
}
}
return s;
}
}
13)join可以用来临时加入线程执行。当A线程执行到了B线程的.join()方法时,A就会等待。等B线程都执行完,A才会执行。(在调用join()方法前,必须使B线程start())
14)setDaemon(boolean b):调用Thread对象的setDaemon(true)方法可将指定线程设置成后台线程。当所有前台线程死亡时,后台线程随之死亡。
15)要将某个线程设置为后台线程,必须在该线程启动之前设置,也就是说,setDaemon(true)必须在start()方法之前调用,否则会引发IllegalThreadStateExcept
16)改变线程优先级:每个线程都具有一定的优先级,优先级高的线程获得较多的执行机会,每个线程的默认优先级都与创建它的父线程优先级相同。注:不能依靠线程的优先级来决定线程的执行顺序。
17)Thread类提供了setPriority(intn),getPriority()方法来设置和返回指定线程的优先级,其中setPriority(intn)参数范围是1-10之间,也可以使用Thread类如下3个静态常量。
MAX_PRIORITY:其值是10。
MIN_PRIORITY:其值是1。
NORM_PRIORITY:其值是5(默认值)。
18)线程通信:wait(),notify(),notifyAll()这三个方法必须有同步监视器对象(锁)来调用。
a)对于使用synchronized修饰的同步方法,因为该类的默认实例(this)就是同步监视器,所以可以在同步方法中直接调用这3个方法。
b)对于使用synchronized修饰的同步代码块,同步监视器是synchronized后括号里的对象,所以必须使用该对象调用这3个方法。
19)死锁:当两个线程相互等待对方释放同步监视器时就会放生死锁。一旦出现死锁,整个程序既不会放生任何异常,也不会给出任何提示,只是所有线程处于阻塞状态,无法继续。
20)包装线程不安全的集合:ArrayList,LinkedList,HashSet,TreeSet,HashMap,TreeMap等都是线程不安全的。可以使用Collections提供的静态方法把这些集合包装成线程安全的集合。
21)如果需要把某个集合包装成线程安全的,则应该在创建之后立即包装,如:
HashMaphm=Collections.synchronizedMap(new HashMap());