此文转载 小舒的java世界 http://www.blogjava.net/zhengshuli-j2ee/articles/258068.html
关于 java多线程学习总结
小弟的第二篇j2se学习笔记,如果有错误或者遗漏的地方,还恳请各位高手老鸟们不要见笑,多给小弟一些批评,建议!
一、线程的基本概念
简单的说:线程就是一个程序里不同的执行路径
在同一个时间点上cpu只会有一个线程在执行
Java里的多线程是通过java.lang.Thread类来实现的
每个线程都拥有自己独立的方法栈空间
二、java线程的创建和启动
第一种
定义线程类实现Runnable接口
Thread myThread = new Thread(target) //target为Runnable接口类型
Runnable中只有一个方法:
public void run();用以定义线程运行体
第二种
可以定义一个Thread的子类并重写其run方法:
clas MyThread extends Thread{
public void run(){}
}
线程类必须通过执行Thread的start()方法启动一个新的线程
如果调用run()方法是属于方法的调用,不会启动一个新的线程
推荐使用第一种方式创建线程,使用接口较为灵活
二、线程状态装换
调用线程start()方法时,线程进入就绪状态,Cpu分配时间片,线程进入运行状态
时间片结束,run()方法未执行完,线程进入阻塞状态。
三、线程控制基本方法
isAlive() //判断线程是否还“活着”,即线程是否还未终止
getPriority() //获得线程的优先级数值
setPriority() //设置线程的优先级指数
Thread.sleep() //静态方法,将当前线程睡眠指定毫秒数
join() //调用某线程的该方法,将当前线程与该线程合并,
//即等待该线程结束,再回复当前线程的运行。
yield() //让出CPU,当前线程进入就绪状态等待调度
interrupt() //中断线程
wait() //当前线程进入对象的wait pool
notify()/all //唤醒对象的wait pool中的一个/所有等待线程
四、sleep方法
Thread的静态方法
public static void sleep(long millis)throws InterruptedException
必须对异常进行捕捉
Thread.currentThread(); //拿到当前线程
五、interrupt方法一种让线程退出的方式。
import
java.util.
*
;
public
class
TestInterrupt{
public
static
void
main(String[] args){
MyThread t
=
new
MyThread();
t.start();
try
{Thread.sleep(
10000
);}
catch
(InterruptedException i){}
t.interrupt();
}
}
class
MyThread
extends
Thread{
public
void
run(){
while
(
true
){
try
{
System.out.println(
"
------
"
+
new
Date()
+
"
-----
"
);
Thread.sleep(
1000
);
}
catch
(InterruptedException i){
return
;
}
}
}
}
六、join和yield方法
t.join(); //t的run()方法完才会继续执行当前线程方法体
//也就是两个线程变成了一个线程
t.yield(); //暂停当前正在执行的线程对象,并执行其他线程。方法为静态
//哪个线程体执行此方法,哪个线程让步
public
class
TestYield {
public
static
void
main(String[] args) {
MyThread3 t1
=
new
MyThread3(
"
t1
"
);
MyThread3 t2
=
new
MyThread3(
"
t2
"
);
t1.start(); t2.start();
}
}
class
MyThread3
extends
Thread {
MyThread3(String s){
super
(s);}
public
void
run(){
for
(
int
i
=
1
;i
<=
100
;i
++
){
System.out.println(getName()
+
"
:
"
+
i);
if
(i
%
10
==
0
){
yield();
}
}
}
}
七、线程优先级别
线程的优先级用数字表示,范围从1到10,一个线程的缺省优先级为5.
Thread.MAX_PRIORITY=1
Thread.MIN_PRIORITY=10
Thread.NORM_PRIORITY=5
例:t.setPriority(Thread.NORM_PRIORITY+3);
★八、线程同步
1.同步代码块
synchronized(this){ //在执行代码块过程中,不会被其他线程打断
...
}
public sunchronized void method //执行此方法时,当前对象被锁定
在Java语言中,引入了对象互斥锁的概念,保证共享数据操作的完整性,每个对象 都对应一个可称为"互斥锁"的标记,这个标记保证在任一时刻,只能有一个线程访 问该对象。
2.线程死锁
public
class
TestDeadLock
implements
Runnable {
public
int
flag
=
1
;
static
Object o1
=
new
Object(), o2
=
new
Object();
public
void
run() {
System.out.println(
"
flag=
"
+
flag);
if
(flag
==
1
) {
synchronized
(o1) {
try
{
Thread.sleep(
500
);
}
catch
(Exception e) {
e.printStackTrace();
}
synchronized
(o2) {
System.out.println(
"
1
"
);
}
}
}
if
(flag
==
0
) {
synchronized
(o2) {
try
{
Thread.sleep(
500
);
}
catch
(Exception e) {
e.printStackTrace();
}
synchronized
(o1) {
System.out.println(
"
0
"
);
}
}
}
}
public
static
void
main(String[] args) {
TestDeadLock td1
=
new
TestDeadLock();
TestDeadLock td2
=
new
TestDeadLock();
td1.flag
=
1
;
td2.flag
=
0
;
Thread t1
=
new
Thread(td1);
Thread t2
=
new
Thread(td2);
t1.start();
t2.start();
}
}
九、生产者消费者问题
public
class
ProducerConsumer {
public
static
void
main(String[] args) {
SyncStack ss
=
new
SyncStack();
Producer p
=
new
Producer(ss);
Consumer c
=
new
Consumer(ss);
new
Thread(p).start();
new
Thread(p).start();
new
Thread(p).start();
new
Thread(c).start();
}
}
class
WoTou {
int
id;
WoTou(
int
id) {
this
.id
=
id;
}
public
String toString() {
return
"
WoTou :
"
+
id;
}
}
class
SyncStack {
//
栈实现
int
index
=
0
;
WoTou[] arrWT
=
new
WoTou[
6
];
//
相当于装物品的篮子
public
synchronized
void
push(WoTou wt) {
//
生产物品,线程安全
while
(index
==
arrWT.length) {
//
当篮子满了线程等待
try
{
this
.wait();
}
catch
(InterruptedException e) {
e.printStackTrace();
}
}
this
.notifyAll();
//
开始生产时,叫醒等待的其他线程开始消费
arrWT[index]
=
wt;
index
++
;
}
public
synchronized
WoTou pop() {
//
消费物品,线程安全
while
(index
==
0
) {
//
如果篮子空了
try
{
this
.wait();
//
线程等待,等待生产者开始
//
生产,叫醒此线程
}
catch
(InterruptedException e) {
e.printStackTrace();
}
}
this
.notifyAll();
//
消费时喊醒生产者生产
index
--
;
return
arrWT[index];
}
}
class
Producer
implements
Runnable {
//
生产者类
SyncStack ss
=
null
;
Producer(SyncStack ss) {
this
.ss
=
ss;
}
public
void
run() {
for
(
int
i
=
0
; i
<
20
; i
++
) {
//
生产20个
WoTou wt
=
new
WoTou(i);
ss.push(wt);
System.out.println(
"
生产了:
"
+
wt);
try
{
Thread.sleep((
int
)(Math.random()
*
200
));
}
catch
(InterruptedException e) {
e.printStackTrace();
}
}
}
}
class
Consumer
implements
Runnable {
SyncStack ss
=
null
;
Consumer(SyncStack ss) {
this
.ss
=
ss;
}
public
void
run() {
for
(
int
i
=
0
; i
<
20
; i
++
) {
//
消费20个
WoTou wt
=
ss.pop();
System.out.println(
"
消费了:
"
+
wt);
try
{
Thread.sleep((
int
)(Math.random()
*
1000
));
}
catch
(InterruptedException e) {
e.printStackTrace();
}
}
}
}