1. 进程:执行中的程序(程序是静态的概念,进程是动态的概念)
2. 线程的实现由两种方式:第一种方式是继承Thread类,然后重写run方法;第二种是实现Runable接口,然后实现其run方法。
3. 将我们希望线程执行的代码放到run方法中,然后通过start方法来启动线程,start方法首先为线程的执行准备好系统资源,然后再去调用run方法。当某个类继承Thread之后,该类就叫做一个线程类。;
4. 一个进程至少要包含一个线程。
5. 对于单核CPU来说,某一时刻只能有一个线程在执行(微观串行),从宏观角度来看,多个线程在同时执行(宏观并行)。
6. 对于双核或者双核以上的CPU老说,可以做到真正的微观并行。
7. a):Thread类实现了Runnable接口,因此实现了Runnable中的run()方法;
8.
b):当生成一个线程对象时,如果没有为其设定名字,那么线程对象的名字将使用如下形式:Thread-number,该number将是自动增加的,并且被所有的Thread对象所共享(因为它是static的成员变量)。
c):当使用第一种方式来生成对象时,我们需要重写run方法,因为Thread类的run方法此时什么事情都不做
d):当使用第二种方式来生成线程对象时,我们需要实现Runnable接口的run方法,然后使用new Thread(newMyThread())(假如MyThread已经实现了Runnable接口)来生成线程对象,这是的线程对象的run方法就会调用MyThread类的run方法,这样我们自己编写的run方法就执行了.
9. Runnable 和继承Thread的方法区别:
在程序开发中只要是多线程肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下好处:
避免点继承的局限,一个类可以继承多个接口。
适合于资源的共享
publicclass Thread extends Object implements Runnable
发现Thread类也是Runnable接口的子类。
10. 关于成员变量与局部变量:如果一个变量是成员变量,那么多个线程对同一个对象的成员变量进行操作时,他们对该成员变量是彼此影响的(也就是说一个线程对成员变量的改变会影响到另一个线程)。
11. 如果一个变量是局部变量,那么每一个线程都会有一个该局部变量的拷贝,一个线程对该局部变量的改变不会影响到其他的线程。
12. 停止线程的方式:不能使用Thread类的stop方法来终止 线程的执行,一般要设定一个变量,在run方法中是一个循环,循环每次检查该变量,如果满足条件则继续执行,否则跳出循环,线程结束。
13. Synchronized关键字:当synchronized关键字修饰一个方法的时候,该方法叫做同步方法。
14. Java中的对象都只有一个锁(lock)或者叫做监视器(monitor),当访问某个对象的synchonized表示将该对象上锁,此时其他任何线程都无法再去访问该synchroized方法了,直到之前的那个线程执行方法完毕后(或者是抛出了异常),那么该对象的锁释放掉,其他线程才有可能再去访问该synchronized方法.
15. 如果一个对象有多个synchronized方法,某一个时刻某个线程已经进入到了某个synchronized方法,那么在该方法没有执行完毕之前,其他线程是无法访问该对象的任何synchronized方法的.
如果某个synchronized方法是static的,那么当线程访问该方法时,它的锁并不是synchronized方法所在的对象,而是synchronized方法所在的对象所对应的Class对象,因为Java中无论一个类有多少个对象,这些对象会对应唯一一个Class对象,因此当线程分别访问同一个类的两个对象static,synchronized方法时,他们的执行顺序也是顺序的,也就是说一个线程先去执行方法,执行完毕后另一个线程才开始执行
1. Synchronized方法是一种粗粒度的并发控制,某一时刻,只能有一个线程执行该synchronized方法;synchronized块则是一种细粒度的并发控制,只会将块中的代码同步,位于方法内,synchronized块之外的代码是可以被多个线程同时访问到的。
2. Wati与notify方法都是定义在Object类中,而且是final的,因此会被所有的Java类继承并且无法重写的,这两个方法要求在调用时,线程应该已经获得了对象的锁,因此对这两个方法的调用需要放在synchronized方法或块中,当线程执行了wait方法时,它会释放掉对象的锁。
3.假如有三个线程Thread1、Thread2和Thread3都在等待对象object A的monitor,此时Thread4拥有对象object A的monitor,当在Thread4中调用object A.notify()方法之后,Thread1、Thread2和Thread3只有一个能被唤醒。注意,被唤醒不等于立刻就获取了object A的monitor。假若在Thread4中调用object A.notifyAll()方法,则Thread1、Thread2和Thread3三个线程都会被唤醒,至于哪个线程接下来能够获取到object A的monitor就具体依赖于操作系统的调度了。上面尤其要注意一点,一个线程被唤醒不代表立即获取了对象的monitor,只有等调用完notify()或notifyAll()并退出synchronized块,释放对象锁后,其余线程才可获得锁执行。
4. 另一个会导致线程暂停的方法是Thread类的sleep方法,它会导致线程睡眠指定的毫秒数,但线程在睡眠的过程中是不会释放掉对象的锁的。