线程与多线程
1. 线程
线程:一个线程是进程的一条执行路径,拥有多个线程的进程可以同时完成各种功能。(各个线程彼此独立)
- 多线程并发执行仅在逻辑上同时,事实上,java虚拟机的执行动作在不同的执行空间来回切换,直至所有线程的任务均实现为止。
- 当某一线程在执行时,其他线程均停止。
- java虚拟机只负责main()主线程的启动。
- 只能由java虚拟机决定哪一个线程被执行,但设计程序时可以人为导向一下(仅供虚拟机参考)interrupt、yield、sleep、wait、notify、join等。
如何创建线程对象?
- 继承Thread类
自定义一个继承Thread类的子类,再覆盖Thread类中的run方法。
由于子类仅能继承一个类,此种方法局限性较大,不建议。
class MyThread extends Thread{
@Override
public void run(){
....//待执行的任务
}
}
- 实现Runnable接口
(1)自定义类实现Runnable接口,override run方法;
(2)new自定义类;
(3)利用对象new一个Thread对象。
该种方式更为灵活
/*实现Runnable接口的类的对象可以被Runnable接口定义的变量引用*/
class MyRunnable implements Runnable{
@Override
public void run(){
....//待执行的任务
}
}
MyRunnable XX = new MyRunnable();
Thread MyThread = new Thread(XX);
注意:
- Thread对象在没有调用start()之前只是个普通的对象,调用start()之后才是真正的线程。
- Thread对象不可以被重复使用,不可以再调用start()指定新任务,一旦线程的run()方法完成后,该线程不能再重新启动,留下来的是普通对象。
线程状态:
(1)创建态
(2)就绪态
(3)运行态
(4)阻塞态
(5)消亡态
2. 多线程
-
problem: 多个线程会产生并发性问题(两个以上的线程存取单一对象的数据,不知道自己的数据被另一线程中的程序改变)。
-
思考: 多线程操作时必须同步变量的变化,如何同步变量的变化?synchronized
(1)同步方法(处理变量的方法每次只能被单一线程使用)
(2) 同步一行或数行指令(同步化不可分割的原子单元(此处非常重要),否则,哪怕每一行都加上锁,动作间仍有被插断的可能)。 -
解决方法: 每一个对象都有一对“锁和钥匙”。 上“锁”。
问题来了,锁的是谁?方法、成员变量、线程本身,----锁的是对象。
(1)对象上的锁只会在有同步化的方法上起作用。
(2)一旦某个线程进入该对象的同步化方法A(持有对象的钥匙),其他线程就无法进入该对象上的任何同步化方法,直到方法A结束。
线程状态:
(1)创建态
(2)就绪态
(3)运行态
(4)阻塞态----等待阻塞态、互斥阻塞态
(5)消亡态