进程:每个进程都有独立的代码和数据空间(进程上下文),是动态的。
线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器,线程切换开销小。
线程和进程的生命周期:创建、就绪、运行、阻塞、终止。
多进程是指操作系统能同时运行多个(程序)。
多线程是指在同一程序中有多个流在执行。
java中的线程实现方式有两种:一种是继续Thread类,另外一种是实现Runable接口
首先先讲一下通过集成Thread类来实现线程。
代码如下:
package chatFunction; /** * * @author ZhangYong * @进程 */ public class test extends Thread { private int count = 10; public void run() { while (count > 1) { synchronized (this) { System.out.println("第 " + Thread.currentThread().getName() + (count--) + " 张票"); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public static void main(String[] args) { test t1 = new test(); Thread t = new Thread(t1, "1号窗口"); t.start(); } }
第二种就是通过Runnable来实现线程
package chatFunction; /** * * @author ZhangYong * @进程 */ public class test implements Runnable { private int count = 10; public void run() { while (count > 1) { synchronized (this) { System.out.println("第 " + Thread.currentThread().getName() + (count--) + " 张票"); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public static void main(String[] args) { test t1 = new test(); Thread t = new Thread(t1, "1号窗口"); t.start(); } }
具体的实现方式都差不多。
二:Thread和Runnable的区别
主要是在一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。
三:多线程的作用:发挥多核cpu的优势,防止阻塞,便于建模
四:tart()与run()方法的区别:
start()才算是真正开始了一个线程,但是调用run()方法就相当于只是执行了一个简单类的调用。run()并不能不同步的执行代码,他是必须等待一个run方法中的代码执行完后才能执行其他run方法。
五:Runnable接口和callable接口的区别
Runnable接口中的run方法返回的是void。她只是存粹的执行了run的代码块,但是callable中的call方法是有返回值的,是一个泛型,和Future配合可以获取一步的执行结果。
六:volatile关键字:
1.多线程主要围绕可见性和原子性两个特性展开的,使用volatile关键字修饰变量,保证了多线程之间的可见性,每次读到的volatile变量总是最新值。eg定义一个volatile变量: volatile int count = 100;
2.禁止语义重排序。
七:线程安全
不可变u,比如像String类型的类,之不会改变的
绝对线程安全
相对线程安全
线程非安全,比如说像arraylist类就是线程非u安全类
八:线程之间共享数据
通过wait/notifu/notifyAll进行唤醒和等待。
九: 现成的互斥和同步
简单的说就相当于,一大群男生追求一个女生,想要和女生约会。但是女生只能和一个人约会,那么这些男的就相当于进程中的互斥,但是女生说今天来那个,不想约会,那么男生们就进入等待,当女生说那个完了,男生们又开始追求,那么他们是在同一起跑线上追求的,现在男人们属于同步。这个时候,女人的信物就相当于是一把锁。只要拥有锁对象就能和女生约会。女生就相当于线程中的公共资源。比如说火车票环节。多个窗口就相当男人,票就相当于女人,那么锁就是锁对象lock。
十:sleep方法和wait方法的区别
sleep和wait都可以用来放弃cpu一定的时间,但是如果线程持有某个监视器,那么sleep不会放弃这个对象监视器,wait就会放弃这个对象监视器。
十一:生产者消费者模型
1.通过平衡生产者的生产能力和消费者的消费能力来提升真个系统的运行效率。这是生产者消费者的最重要的作用。
2.解耦。解决生产者和消费者之间松耦合。
十二:如何检测一个线程是否持有对象监视器
Thread类提供了一个holdsLock(Object obj)方法,当仅当对象obj的监视器被当前线程持有的时候才会返回true,这是一个static方法。
十三:什么是乐观锁和悲观锁
乐观所:针对线程安全来说,认为并发间的线程竞争不会经常发生
悲观锁反之
十四:比如说现在有线程一二三,如何保证二在一线程执行完后执行,三在二线程执行完后执行。
采用线程join方法执行
十五:在java中lock接口比synchronized快的优势?
lock的优势主要体现在lock对读和写都提供了锁机制。
十六:java实现阻塞队列
wait方法和notify方法
十七:
sleep(): 强迫一个线程睡眠N毫秒。
isAlive(): 判断一个线程是否存活。
join(): 等待线程终止。
activeCount(): 程序中活跃的线程数。
enumerate(): 枚举程序中的线程。
currentThread(): 得到当前线程。
isDaemon(): 一个线程是否为守护线程。
setDaemon(): 设置一个线程为守护线程。(用户线程和守护线程的区别在于,是否等待主线程依赖于主线程结束而结束)
setName(): 为线程设置一个名称。
wait(): 强迫一个线程等待。
notify(): 通知一个线程继续运行。
setPriority(): 设置一个线程的优先级。