-
Notifications
You must be signed in to change notification settings - Fork 0
yangyp8110 edited this page Jan 17, 2018
·
1 revision
run 与 start区别:
//1、run与start的区别
Thread t1 = new Thread();
//t1.run();//仅作普通方法调用,未新开一个线程
t1.start();//新开一个线程执行
//2、默认Run什么都没做,可以重写Run方法
Thread t2 = new Thread() {
@Override
public void run() {
System.out.println("hello");
}
};
t2.start();
默认的Thread.run方法是直接调用Runnable接口,因此一般实现Runnable接口告诉线程要执行的任务
class CreateThread3 implements Runnable{
@Override
public void run() {
System.out.println("this is runnable implements");
}
}
Thread t1 = new Thread(new CreateThread3());
t1.start();
Thread.stop方法会直接终止线程,并且立即释放线程所持有的锁(可能会破坏对象的一致性,已被弃用的方法)
线程中断
public void test3() throws InterruptedException {
// Thread.interrupt() ==> 中断线程(设置中断标识位,目标线程自行决定何时退出)
// Thread.isInterrupted() ==>判断是否中断
// Thread.interrupted() ==> 判断是否被中断,并清除当前中断状态
Thread t1 = new Thread() {
@Override
public void run() {
while (true) {
System.out.println("thread running");
if (Thread.currentThread().isInterrupted()) {
System.out.println("thread interrupted");
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
//Thread.sleep()中断会抛出interruptedException,此时捕捉到异常信息后,会清除中断标记,所以需要重新设置
//当前线程的interrupted状态,否则下一次循环在 Thread.currentThread().isInterrupted() 无法读取到中断状态
//程序就不会退出(Thread.interrupt方法不会破坏一致性)
Thread.currentThread().interrupt();
}
}
}
};
t1.start();
Thread.sleep(2000);
t1.interrupt();
}
wait和notify必须包含在对应的synchronzied语句中,需要先获取目标对象的监视器
- wait与sleep
- 相同点:都可以让线程等待若干时间
- 不同点:
- wait可以被唤醒
- wait会立即释放目标对象锁;sleep不会释放锁
public class test4Class {
final static Object object = new Object();
public static class Thread1 extends Thread {
public void run() {
synchronized (object){
System.out.println(System.currentTimeMillis() +": Thread1 start !");
try{
System.out.println(System.currentTimeMillis()+": Thread1 wait for object");
object.wait();
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(System.currentTimeMillis()+": Thread1 interrupt ");
}
System.out.println(System.currentTimeMillis()+": Thread1 end ! ");
}
}
}
public static class Thread2 extends Thread{
public void run(){
synchronized (object){
System.out.println(System.currentTimeMillis() +": Thread2 start ! notify one thread");
object.notify();
System.out.println(System.currentTimeMillis()+": Thread2 end !");
try{
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(System.currentTimeMillis()+": Thread2 interrupt ");
}
}
}
}
}
测试结果:
public void test4(){
/**
* 输出:
1496671756464: Thread1 start !
1496671756465: Thread1 wait for object
1496671756465: Thread2 start ! notify one thread
1496671756465: Thread2 end !
1496671758465: Thread1 end ! (相比上一步,间隔2秒,t2释放锁后,t1拿到object锁才继续执行)
结论:
1>wait会先获得锁,然后wait执行后立即释放锁(第二行与第三行无时间间隔)
2>notify后,thread1需要重新获取锁(等待notify释放锁(最后两行间隔2秒)),然后再继续执行
*/
test4Class.Thread1 t1 = new test4Class.Thread1();
test4Class.Thread2 t2 = new test4Class.Thread2();
t1.start();
t2.start();
}
join(等待线程结束)与yield(谦让)
synchronzied(同步锁)
- 指定加锁对象:对给定对象加锁,进入同步代码前需要先获得给定对象的锁
- 直接作用于示例方法:相当于对当前实例加锁,进入同步代码前要获得当前实例的锁
- 直接作用于静态方法:相当于对当前类加锁,进入同步代码前需要获得当前类的锁
线程组
public class test5Class {
public static class ThreadGroupName implements Runnable{
@Override
public void run() {
String groupName = Thread.currentThread().getThreadGroup().getName()
+"-" +Thread.currentThread().getName();
while (true){
System.out.println("I am "+ groupName);
try{
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
运行结果:
public void test5(){
/**
* 线程组 ThreadGroup
*/
ThreadGroup group = new ThreadGroup("myGroup");
Thread t1 = new Thread(group,new test5Class.ThreadGroupName(),"t1");
Thread t2 = new Thread(group,new test5Class.ThreadGroupName(),"t2");
t1.start();
t2.start();
System.out.println(group.activeCount());
group.list();
}