1、并发和并行的区别?
并发可以发生在一个或多个CPU,同时处理多个任务,多个任务之间可以进行切换执行;并行只能发生在多核CPU,一核对应一个任务同时运行
2、线程和进程之间的区别?
a) 一个程序至少有一个进程,一个进程至少有个线程
b) 进程在执行过程中拥有独立的内存单元,线程之间的内存却是共享的
c) 线程不能独立运行,必须依赖进程
举个例子:
我们执行一个Main方法,里面其5个线程进行打印操作,这是Main方法执行是一个进程,我们可以通过jps看到他的进程Id,但是这一个进程里面却有5线程在同时运行。
3、实现多线程的方式?
public class Test {
//此方式不够灵活,由于Java的单继承性,不能再继承其他类了
static class ExtendsThread extends Thread{
@Override
public void run() {
System.out.println("extends run...");
}
}
// 推荐这种,java可以实现多个接口,只能继承一个类
static class RunnableThread implements Runnable{
@Override
public void run() {
System.out.println("implements run...");
}
}
public static void main(String[] args) {
ExtendsThread thread1 = new ExtendsThread();
thread1.start();
Thread thread2 = new Thread(new RunnableThread());
thread2.start();
}
}
4、线程的状态有哪些?
通过Thread类的enum State可以看到
NEW:新建了一个线程对象还未调用start
RUNNABLE:就绪(ready)和运行中(running)统称为运行,Running和Runnable可以互相切换,线程运行一段时间被另一个高优先级线程抢占之后从running编程Runnable状态。sleep到时间;IO返回;成功获得同步监视器;挂起线程resume恢复。
BLOCKED:阻塞于锁;调用sleep;阻塞IO;等待通知。
WAITING:线程需要等待其他线程做出一些通知或中断动作,例如:调用wait()方法,需要等待notify唤醒。
TIMED_WAITING:超时等待,他可以在指定时间后自行返回
TERMINTED:线程执行完毕
5、System.out.println原理是?
内部是在synchronized代码块中调用OutputStream的write方法
6、线程处于准备运行和正在运行Thread.isAlive()返回都是true
7、wait和notify的说明
两个方法必须都在同步代码块中,并且锁的对象是同一个,即两个方法是互斥的,不能同时运行,并且是先执行wait再执行notify,否则线程将无限阻塞下去。
如果两个方法不在同步代码块或者锁的不是同一个对象将会报java.lang.IllegalMonitorStateException
8、关于Thread.sleep()、Thread.yield()、Thread.join()、wait()的说明
sleep方法并不会释放锁,只是释放CPU的占用权,睡眠时间到了以后然后和其他线程(包括优先级比当前线程高、低的都可以)再竞争CPU占用权。
yield和sleep类似,只是不能指定睡眠时间,并且线程让步完成之后只能相同优先级的线程可以进行竞争。
join的作用是使调用了join先执行完,后面的线程才能继续执行,我们可以传入等待的时间join(1000),他的底层是使用synchronized,根据线程isAlive来进行wait操作,当调用join的线程执行完毕之后会notify下一个等待的线程。
wait是当前线程释放锁,暂停执行,等待notify(不会立即释放锁,需要等待代码块执行完毕)线程唤醒,且等待notify线程执行完再继续执行。
9、终止线程的几种方式?
Thread.stop:强制终止,他会终止正在运行的线程,不推荐使用,他的底层使用的resume方法。
Thread.suspend:暂停,Thread.resume唤醒;两个都是独占锁,暂停不推荐使用,暂停之后可以出现数据不同步问题,例如:
一个线程执行两个操作,setName(a),然后执行suspend,导致setAge(10)无法完成赋值。
Thread.interrupt中断线程,他会优雅的停止,如果当前线程正在运行,他会等线程运行完毕之后再结束,推荐使用。
10、指定线程优先级Thread.setPriority(N); 1<=N<=10,子类和父类的优先级相同
11、守护线程
典型的守护线程是垃圾回收线程,当进程中没有用户线程,守护线程就没有存在的必要了。守护线程就是一直坚守着用户线程,并为其提供着一些服务。
12、synchronized关键字的几点说明
a) 多个synchronized(this)同一个对象不能并发,多个对象可以并发
b) synchronized(this)与synchronized方法同上
c) synchronized(任意对象)与synchronized方法同上
d) 多个synchronized普通方法同上
e) synchronized方法与synchronized(*.class),同一个对象可以并发,不能对象不能并发
f) 静态synchronized方法与synchronized(*.class)无论同一个对象还是多个都不能并发执行
g) synchronized(*.class)之间不能并发执行
h) 多个synchronized 静态方法之间不同同时运行,一个synchronized static方法和一个synchronized非 static方法之间可以同时运行
synchronized具有可重入特性
synchronized里面代码抛出异常锁会自动释放
synchronized不能继承
synchronized(obj)obj一般不用String类型,容易造成线程阻塞
13、volatile关键字
当多个线程对一个全局变量进行操作时,每个线程会把这个变量从主内存拷贝到自己私有CPU高速缓存中,如果每次都读主存效率会比较低,因此当一个线程修改这个变量时其他线程是感觉不到的,就会产生线程安全问题,如果使用volatile修饰,当一个线程对变量修改时(一旦修改即同步到主存中),另一个线程所读取的变量值会被迫失效,这时候会从新从主存中读取。