一、 线程的生命周期
1、创建状态
使用构造方法,创建线程对象Thread t = new Thread();
2、可运行状态(就绪状态)
通过调用线程的start方法 t.start();
3、运行状态,run方法被执行的过程
4、阻塞状态
线程休眠(sleep),等待输入输出(IO),调用了wait()
5、终止状态
run()执行完毕
检测线程是否还活着,可以使用线程的isAlive()方法来判断
while(t.isAlive()){
System.out.println("子线程还活着");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
二、 子线程的其他功能
1、线程加入:join()方法可以加入其他的线程先执行,然后再执行后面的内容join方法可以加时间,表示可以加入一段时间
JoinThread t = new JoinThread();
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
JoinThread2 t2 = new JoinThread2();
t2.start();
try {
t2.join(300);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
2、将线程变为守护线程
//将该线程变为守护线程(主线程执行完了它也完了)
t.setDaemon(true); //该方法必须要放在start之前
t.start();
3、线程优先级
// 设置线程的优先级,最低为1,最高是10,默认是5
t2.setPriority(10);
t1.setPriority(1);
4、线程同步
关键字synchronized:可以修饰代码块、方法,可以保证在同一时间只有一个线程执行该段代码。
语句块
synchronized (共享的对象) {
//代码块内容
}
synchronized (this) {
if (money > 0) {
System.out.println(Thread.currentThread().getName() + "取100");
money -= 100;
System.out.println(Thread.currentThread().getName() + "取完了,余额"
+ money);
}else{
System.out.println(Thread.currentThread().getName() + "来取,没钱了");
}
}
方法
public synchronized void getMoney(){
//方法体
}
当一个线程访问某个对象的一个synchronized(this)同步块时,其他线程对该对象中的其他synchronized(this)同步语句块也将被阻塞.
5、 wait和notify
每个对象中都可以从Object上继承wait和notify(以及notifyAll)方法,wait方法会导致调用的线程进入阻塞,直到调用该对象的notify或者notifyAll为止
//让线程阻塞
synchronized (obj) {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//唤醒调用了wait导致阻塞的线程
synchronized (o) {
//唤醒线程
o.notify();
}
注意一个notify只能唤醒一个wait
三 、 线程池
由于频繁创建线程,销毁线程会导致很多的资源浪费,因此可以使用线程池来管理这个过程。
使用:
1、定义Runnable类型
class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 30; i++) {
System.out.println(Thread.currentThread().getName() + "==>" + i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
2、创建要执行的任务(Runable对象)
MyRunnable r1 = new MyRunnable();
MyRunnable r2 = new MyRunnable();
MyRunnable r3 = new MyRunnable();
3、创建线程池对象
ExecutorService es = Executors.newCachedThreadPool();
4、执行任务
es.execute(r1);
es.execute(r2);
如果任务执行完了,需要关闭线程池,那么可以使用线程池对象的shutDown方法
es.shutdown();
shutDown跟shutDownNow的区别是后者直接关闭所有任务不管是否在执行
5、关于Future
当在线程池中使用submit方式提交任务是可以得到一个Future对象,该对象可以检测该任务执行状态(是否完毕、是否被取消),也可以直接取消任务
Future<?> f = es.submit(r2);
...
//如果未执行完毕则取消
if (!f.isDone()) {
f.cancel(true);
}
该取消方式主要是使用线程的InterruptedException
Java的线程控制方法和线程池
最新推荐文章于 2024-08-07 22:00:54 发布