进程:进程指正在运行的程序。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能。
线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。
在java中实现线程的方式有:继承Thread类和实现Runnable接口。推荐使用实现接口的方式,因为一个类实现接口可以有多个,但是只能继承一个父类。
开启线程的方式:start()方法被用来启动新创建的线程,而且start()内部调用了run()方法,这和直接调用run()方法的效果不一样。当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程。(start启动新线程,run在原来线程中启动)
悲观锁:就是不管是否发生多线程冲突,只要存在这种可能,就每次访问都加锁,加锁就会导致锁之间的争夺,有争夺就会有输赢,输者等待。
乐观锁:获得锁后一直持有锁以防本线程再次申请该锁造成无谓的解锁再加锁开销。
多线程模拟售票抢票窗口:
public static void main(String[] args) {
MyThread3 t = new MyThread3();
Thread t1 = new Thread(t);
t1.setName("窗口1:");
t1.start();
Thread t2 = new Thread(t);
t2.setName("窗口2:");
t2.start();
Thread t3 = new Thread(t);
t3.setName("窗口3:");
t3.start();
}
}
class MyThread3 implements Runnable {
int ticket = 100;
Object lock = new Object();
@Override
public /*synchronized*/ void run() {
while (true) {
//同步代码块 安全性高 (票不会重复 负数)
synchronized(lock) {
if (ticket > 0) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":" + ticket--);
}
}
}
}
- 同步代码块比同步方法,同步代码块可以让我拥有对锁的可控权。
- 同步块是更好的选择,因为它不会锁住整个对象(当然也可以让它锁住整个对象)。同步方法会锁住整个对象,哪怕这个类中有多个不相关联的同步块,这通常会导致他们停止执行并需要等待获得这个对象上的锁。
线程同步异步:
同步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为同步机制存在,A线程请求不到,怎么办,A线程只能等待下去
异步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为没有同步机制存在,A线程仍然请求的到,A线程无需等待
线程生命周期: