1.进程与线程
进程:操作系统中程序的一次执行过程或一个周期,是操作系统资源分配的最小单元
线程:进程的一个子任务,是操作系统任务分配的最小单元,在一个进程中的所有线程共享进程资源
进程与线程区别:
1)进程是操作系统资源分配的最小单元,线程是操作系统任务分配的最小单元
2)进程的启动与销毁开销较大,与此相比,启动与销毁一个线程,开销要小的多
3)进程间通信远比线程间通信复杂得多
java中main方法是一个线程
高并发:在同一时刻,并发访问的数量非常多
线程的状态:
Java线程实现:
无论使用哪种方式创建线程,启动线程一律使用start()方法
start()方法,只能被执行一次,执行多次会抛出IllegalThreadException
1).继承Thread类,而后覆写run()方法(线程任务)
2).实现Runnable接口,而后覆写run方法
java中Thread类本身也实现了Runnable接口,与用户自定义的线程类共同组成代理设计模式
其中Thread类实现辅助操作,包括线程的资源调度等任务;自定义线程类完成真实业务
继承Thread类与实现Runnable接口区别:
I.继承Thread类有单继承局限,相对而言实现Runnable接口更加灵活,并且Thread类本身也实现Runnable辅助真实线程类
II.实现Runnable接口可以更好地实现程序共享的概念(thread类也可以,只不过麻烦一点)
3).实现Callable接口,而后覆写call<V>方法
V call() throws Exception ; 线程任务执行后有返回值
4).线程池
线程休眠:指的是让线程暂缓执行一下,等到了预计时间之后再恢复执行。
sleep()方法会让当前线程立即交出cpu,但不会释放对象锁
线程让步:yeild()
暂停当前正在执行的线程对象,并执行其他线程(只能让拥有相同优先级的线程获取cpu),当前线程不会立即交出cpu,交出时间由系统调整,yeild不释放锁
线程等待:join()
若线程1需要等待线程2执行完毕之后在恢复执行,可以在线程1中调用线程2的join方法,在那个线程中调用那个线程阻塞,等等待线程执行完毕再恢复执行
线程停止:
1).设置一个标志位(无法处理线程阻塞时停止的问题)
2).调用Thread类中的stop()方法强行关闭
本方法现在已经不推荐使用,因为会产生不安全数据
3).调用Thread类提供的interrupt();
3.1)若线程中,没有使用wait、join、sleep方法,调用此线程对象的interrupt方法并不会真正中断线程,只是简单将线程的状态置为interrupt而已,我们可以根据此状态来进一步确定如何处理线程
Thread类提供的isinterrupt可以检测当前线程状态
3.2)若线程调用一个阻塞线程的方法如:
wait、join、sleep方法,此时再调用会抛出异常,同时将线程状态还原(isInterrupt = false)
线程继承性:若在一个线程中创建一个子线程,默认子线程和父线程优先级相同
守护线程:DaemonThread
Java中线程分为两类:用户线程和守护线程
守护线程为陪伴线程,只要jvm中存在任何一个用户线程没有终止,守护线程就一直在工作
默认创建的线程都是用户线程,包括主线程
通过setDaemon(true)将线程对象设置为守护线程
典型的守护线程:垃圾回收线程
多线程编程三大问题:
分工
同步:线程间通信
异步:
java中锁的实现:
使用synchronized关键字为程序逻辑上锁
使用synchronized两种用法:
同步代码块:
synchronized(锁的对象|任意一个Object子类对象|当前类名称.class){
//此处diamante块在任意一个时刻只能有一个线程进入
}
同步方法:
声明方法时加上synchronized 锁当前对象this和当前类名.class
此时表示该方法在任意一个时刻只能有一个线程进入
若synchronized修饰的是静态方法或
synchronized(类名称.class)synchronized锁的是当前类的反射对象(全局唯一)
如何保护有关联的的对象:使用同一把锁