多线程复习笔记之一【关键属性与常用关键字概述】

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修饰,当一个线程对变量修改时(一旦修改即同步到主存中),另一个线程所读取的变量值会被迫失效,这时候会从新从主存中读取。

猜你喜欢

转载自blog.csdn.net/fuyuwei2015/article/details/85016260
今日推荐