Java的线程控制方法和线程池

来源:互联网 发布:mac安装win10 不断重启 编辑:程序博客网 时间:2024/04/30 03:57
         一、 线程的生命周期
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
0 0