1、Java中如果我们自己没有产生线程,那么系统就会给我产生一个线程(主线程,main方法就是在主线程上运行),我们的程序都是由线程来执行的。
2、进程:执行中的程序(程序是静态的概念、进程是动态的概念)。
3、线程的实现由两种方式,第一种方式是继承Thread类,然后重写方法;第二种是实现Runnable接口,然后实现其run方法。推荐使用第二种方式
4、将我们希望线程执行的代码放到run方法中,然后通过start方法来启动线程(只有Thread的start方法才能启动线程,没有其它的方法了。)。start 方法首先为线程的执行准备好系统资源,然后去调用run方法。当某个类继承了Thread之后,该类就叫做一个线程类
5、一个进程至少包含一个线程,线程共享所属进程的资源。
6、对于单核cpu来说,某一时刻只能有一个线程在执行(微观串行),从宏观角度来看,多个线程在同时执行(宏观并行)。多核cpu能真正意义上实现微观并行。
7、
1、Thread类也实现了Runnable接口,因此实现了Runnable接口中的方法
2、当生成一个线程对象时,如果没有为其指定名字,那么线程对象的名字将使用默认的Thread-number形式,number数值是自增的,并且所有的Thread对象共享它,因为它是static成员变量。
3、当使用第一种方式来生成线程对象时,我们需要重写run方法,因为Thread类的run方法什么事情都没有做
4、当我们使用第二种方式生成对象的时,我们需要实现Runnable接口的run方法,然后使用new Thread(Runnable target),target是已经实现了Runnable接口的对象。最后启动线程还是要用到Thread的start方法。但是最终还是会调用target已经重写了的run方法
8、关于成员变量和局部变量:如果一个变量是成员变量,那么多个线程对同一个对象的成员变量操作时,他们对该成员变量是彼此影响的。(也就是说一个线程对成员变量的改变会影响到另一个线程)。注意是对同一个对象操作,如果是不同对象就不存在所谓的影响了。
9、如果一个变量是局部变量,那么每个线程都会有一个该局部变量的拷贝,一个线程对该局部变量的改变不会影响到其他线程。
10、停止线程的方式,不推荐使用Thread类的stop方法来终止线程执行。一般要设定一个变量,在run方法中判断检查该变量,如果该变量无法满足一定条件,那么我们就是run方法跳出循环或break。
11、不能依靠线程的优先级来决定线程的执行顺序(优先级只是相对的,越高代表被cpu调度的机率越大)
12、synchronized关键字:当synchronized关键字修饰一个方法的时候,该方法叫做同步方法。
13、Java中的每一个对象都有一个锁(lock)或者叫做监视器(monitor),当访问某个对象的synchronized方法时,表示将该对象上锁,此时其它任何线程都无法再去访问该synchronized方法了,直到之前的那个线程执行方法完毕后(或者抛出了异常),将该对象的锁释放掉,其它线程才能可以去访问该synchronized方法。
14、如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronized方法,那么在该方法没有执行完毕前,其它线程是无法访问该对象的任何synchronized方法的。
15、如果某个synchronized方法是static的,那么当线程访问该方法时,它的锁并不是synchronized方法所在的对象,而是synchronized方法所在的对象所对应的class对象,因为java中无论一个类有多少个对象,这些对象都会对应唯一一个Class对象,因此当线程分别访问同一个类的两个对象的的两个static,synchronized方法时,他们的执行顺序也是顺序,也就是说一个线程先去执行方法,执行完毕后另一个线程才开始执行。
16、synchronized代码块,格式如下:
synchronized(object){
。 。 。
}
17、synchronized方法是一种粗粒度的并发控制,某一时刻,只能有一个线程执行该synchronized方法;synchronized块则是一种细粒度的并发控制,只会将块中的代码同步,位于方法内、synchronized块之外的代码是可以被多个线程同时访问的。
18、wait与notify方法都是定义在Object类中,而且是final的,因此会被所有的java类所继承并且无法重写。这两个方法要求在调用的时候线程应该已经获得了对象的锁,因此对这两个方法的调用需要放在synchronized方法或块当中。当线程执行了wait方法时,它会释放掉对象的锁。
19、另一个会导致线程暂停的方法是Thread类的sleep方法,它会导致线程睡眠指定的毫秒数,但是线程在睡眠的过程是不会释放掉对象的锁的。(wait 和 sleep 都会使线程暂停,区别在于wait释放了对象的锁,sleep不释放对象的锁。) |
|