一、线程简介
1.线程的概念
系统运行的最小单元
2.为何使用多线程
更好地利用系统资源(处理器多核心),提高响应速度。
3.线程的状态
NEW(创建状态)
RUNABLE(运行状态,系统调度,争抢时间片)
BLOCKED(阻塞状态,加了锁,其它线程获得到了锁)
WATING(等待状态,wait()方法时,使用notify()唤醒)
TIMED_WAITING(超时等待状态,线程sleep()时,)
TERMINAL(线程终止)
关于wait和notify:
public class ThreadTest { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new Waiting(), "WaitingThread"); Thread thread2 = new Thread(new NotifyWaiting(), "NotifyWaitingThread"); thread.start(); TimeUnit.SECONDS.sleep(2); thread2.start(); } } class Waiting implements Runnable { @Override public void run() { synchronized (Waiting.class) { try { System.out.println("Current thread: " + Thread.currentThread().getName() + ",Waiting is waiting!"); Waiting.class.wait(); System.out.println("Current thread: " + Thread.currentThread().getName() + ",Waiting is notified!"); } catch (InterruptedException e) { e.printStackTrace(); } } } } class NotifyWaiting implements Runnable { @Override public void run() { synchronized (Waiting.class) { Waiting.class.notify(); System.out.println("Current thread: " + Thread.currentThread().getName() + ",Waiting is notified!"); } } }
结果:
Current thread: WaitingThread,Waiting is waiting! Current thread: NotifyWaitingThread,Waiting is notified! Current thread: WaitingThread,Waiting is notified!
wait方法会释放锁,sleep则不会
二、启动和终止线程
1.启动线程
1.构建线程
new Thread(); new Runable(); new Callable(); //Callable可以返回Future携带返回值
注意:最好给线程初始化名称,方便JVM分析。
2.启动线程
thread.start();
或者Excutors.new线程池,然后ExecutorService.submit或者excute
2.终止线程
终止线程最好使用一个volatile修饰的boolean开关去进行控制
三、线程之间的通信
1.volatile与synchronized关键字
多个线程共享一个变量的话,会在线程里有一个变量的拷贝,提升运行效率,而导致线程不安全,而 volatile 关键字让变量直接从共享内存中读写,保证变量的安全性,但是效率却降低了。
2.wait()与notify()
wait() 方法与锁对象一起使用,调用wait()方法会释放所对象。
wait()标准范式:
synchronized(对象A){ while(条件不成立) { 对象A.wait(); }
doSomething(); }
notify()标准范式:
synchronized(对象A){
改变条件; 对象A.notify(); }
解读:
(1)wait()方法块,获取锁对象A;
(2)wait()方法块,锁对象A调用wait()方法,释放锁,进入WAIT状态,方法块进入WAIT队列;
(3)notify()方法块,获取所对象A;
(4)notify()方法块,改变条件,wait()方法块处于WAIT状态;
(5)notify()方法块,对象A调用notify()方法,此时wait()方法块离开WAIT队列,进入对象A的阻塞队列中;
(6)notify()方法块释放锁,wait()方法块获得锁,继续执行方法块,doSomething();
3.Thread.join()
在线程A中执行线程B.join():要先执行完线程B终止之后才从线程B.join()返回。
四、线程应用实例
1.等待超时模式
伪代码:
public synchronized Object get(long mills) throws InterruptedException { long future = System.currentTimeMillis() + mills; long remaining = mills; while(result == null && remaining > 0) { wait(mills); remaining = future - System.currentTimeMillis(); } return result; }
解读:在超时mills毫秒之后,返回结果;
2.适用
连接池(连接池超时),线程池(线程池等待超时)