首页 > 代码库 > java 多线程基础
java 多线程基础
线程是进程内的执行单元,进程当中都有若干个线程。
通常主线程或进程是阻塞式的按顺序执行的,如果希望异步执行些子任务,而不要阻塞当前线程的执行,即需要创建子线程,子线程创建后主线程可以等待它们的结果,得到它们的结果后进行其它的操作,但也可以不管它,让它自生自灭。
下面具体看下怎样创建多线程与如何让子主线程互动:
1、到底是start还是run
直接调用run方法是无法开启一个新线程的,应该调用start方法,start方法其实是在一个新的操作系统线程上面去调用run方法。换句话说,直接调用run方法而不是调用start方法的话,它并不会开启新的线程,而是在调用run的当前的线程当中执行你的操作,例如:
Thread thread =
new
Thread(
"t1"
)
{
@Override
public
void
run()
{
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName());
}
};
thread.start();//这样会输出 "t1"
2、终止线程
Thread.stop() 不推荐使用。它会释放所有monitor,stop方法太过”暴力”了,无论线程执行到哪里,它将会立即停止掉线程。
3、线程中断
相比终止线程,更应该使用的是中断线程。
中断是一种协作机制。也就是说调用线程对象的interrupt方法并不一定就中断了正在运行的线程,它只是要求线程自己在合适的时机中断自己。每个线程都有一个boolean的中断状态(不一定就是对象的属性,事实上,该状态也确实不是Thread的字段),interrupt方法仅仅只是将该状态置为true。对于非阻塞中的线程, 只是改变了中断状态, 即Thread.isInterrupted()将返回true,并不会使程序停止;
4、线程挂起
挂起(suspend)和继续执行(resume)线程
- suspend()不会释放锁
- 如果加锁发生在resume()之前 ,则死锁发生
这两个方法都是Deprecated方法,不推荐使用。
原因在于,suspend不释放锁,因此没有线程可以访问被它锁住的临界区资源,直到被其他线程resume。因为无法控制线程运行的先后顺序,如果其他线程的resume方法先被运行,那则后运行的suspend,将一直占有这把锁,造成死锁发生。
5、join和yeild
yeild是个native静态方法,这个方法是想把自己占有的cpu时间释放掉,然后和其他线程一起竞争(注意yeild的线程还是有可能争夺到cpu,注意与sleep区别)。在javadoc中也说明了,yeild是个基本不会用到的方法,一般在debug和test中使用。
join方法的意思是等待其他线程结束,就如suspend那节的代码,想让主线程等待t1,t2结束以后再结束。没有结束的话,主线程就一直阻塞在那里。
join()方法也可以传递一个时间,意为有限期地等待,超过了这个时间就自动唤醒。
6、守护线程
setDaemon(
true
);就可以将线程设置为守护线程
守护线程就是在后台默默地完成一些系统性的服务,比如垃圾回收线程、JIT线程就可以理解为守护线程。
7、线程优先级
Thread类中有3个变量定义了线程优先级。
public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;
让一个高优先级的线程和低优先级的线程同时争夺一个锁,看看哪个最先完成。
当然并不一定是高优先级一定先完成。再多次运行后发现,高优先级完成的概率比较大,但是低优先级还是有可能先完成的。
8. 基本的线程同步操作
synchronized 和 Object.wait() Obejct.notify()
java 多线程基础