多线程总结

1、并行和并发
(1)并行:并行是一个宏观的概念,指在同一时间点上同时运行。譬如CPU是多核的,一个处理听歌,一个处理打游戏。
(2)并发:并发是一个微观概念,指在同一时间段有多个线程运行。譬如在一个进程内,有两个线程,分别听歌和打游戏,那么CPU会分配时间片,线程竞争,感觉像是一起发生,其实不是。
 
2、进程和线程
进程:是一块包含了某些资源的内存区域。操作系统利用进程把它的工作化为一些功能单元。
线程:线程是进程的一个实体,是CPU调度的分派的基本单位。线程基本有不拥有系统资源,只拥有一点在运行时必不可少的资源(如程序计数器,一组寄存器和栈),它与同属与一个进程的其他的线程共享进程所拥有的全部资源。
进程和线程的区别:
进程是不能进行信息共享的,一个进程中的多线程享有该进程的全部资源,是信息共享的(即并发)。
创建进程耗资源,线程相对不耗资源。
一个进程有多个线程,一个线程只归属于一个进程。
3、并发的三种方式:
(1)synchronized修饰方法;
1)修饰静态方法时,锁住的是整个类的class,即这个类的所有对象。
2)修饰非静态方法时,锁住的是访问方法的当前对象;
(2)synchronized修饰方法块;
在修饰代码块时,应减少代码块中并发中的代码。
(3)使用lock;
ReentrantLock lock=new ReentrantLock();
上锁:lock.lock();
释放锁:lock.unlock();
4、Thread状态
1)新建状态(new):新创建一个线程。
2)可运行状态:运行了线程的start()方法。
(1)就绪状态:等待JVM的调度
(2)运行状态:线程对象获得了JVM的调度
3)等待状态:执行了wait()方法
4)计时等待状态:运行了sleep()或者wait()(注:wait方法加了时间参数)方法
5)阻塞状态:join()方法,或者发出了I/O请求
6)终止状态:线程完成或者抛出异常。
5、wait () ,notify () ,notifyAll () 的应用
通常,多线程之间需要协调工作:如果条件不满足,则等待;当条件满足时,等待该条件的线程将被唤醒。
注意:wait(),notify(),notifyAll()三个方法是不属于Thread的,是属于对象的,必须应用到synchronized()修饰过方法或者快的时候。否则会报 Java .lang.IllegalMonitorStateException
6、线程休眠sleep () :让执行的线程暂停一段时间,进入即时等待状态。
注意:sleep()是不释放锁的,wait()是释放锁的。
7、联合线程join ()
强制运行某个线程。
package day1.ThreadThree;
class joinDemo implements Runnable{
 
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("demo"+i);
}
}
}
public class ThreadJoin {
public static void main(String[] args) throws InterruptedException {
Thread td=new Thread(new joinDemo());
for (int i = 0; i < 100; i++) {
System.out.println("main"+i);
if (i==10) {
td.start();
}
if (i==20) {
td.join();
}
}
}
}
主线程在运行第十次的时候,线程td开始运行,这时主线程和线程td依次进行竞争,在主线程i=20时,td运行join,强制运行,当td运行完后,在执行主线程。
 
7、线程优先级
每个线程都有优先级,优先级的高低只和线程获得执行机会的次数多少有关,并非优先级越高的的就一定执行,哪个线程的先运行取决于CPU的调度。
MAX_PRIORITY=10 最高优先级
MIN_PRORITY=1 最低优先级
NORM_PRIORITY=5 默认优先级
每个线程都有默认的优先级,主线程默认优先级是5,如果A线程创建了B线程,那么B线程和A线程拥有相同的优先级。
注意:不同的操作系统支持的线程优先级是不同的,建议使用上述三个优先级,不要自定义。
8、线程礼让
yiled():表示当前线程对象提示调度器自己愿意让出CPU资源,但是调度器可以自由的忽略该提示。
调用该方法后,线程对象进入就绪状态,所以完全有可能:某个线程调用yield()之后,线程调度器又把它调度出来重新执行。
从Java7提供的文档上可以清楚的看出,开发中很少会使用该方法,该方法主要用于调试或测试,它可能有助于因多线程竞争条件下的错误重现现象。
sleep()和yield() 方法的区别:
1)都能使当前处于运行状态的线程放弃CPU,把运行的机会给其他线程。
2)sleep()方法会给其他线程运行机会,但是不考虑其他线程的优先级,yield()方法只会给相同优先级或者更高优先级的线程运行的机会。
3)调用sleep()方法后,线程进入计时等待状态,调用yield()方法后,线程进入就绪状态。
9、前台线程和后台线程
JVM在运行时,会有两个线程。
主线程和后台GC处理线程。
后台线程(即:daemon=false):会在主线程结束后立马停止。
默认为前台线程(),想改为后台线程。
thread.setDaemon(true);
 

猜你喜欢

转载自2902702156.iteye.com/blog/2363715