Skip to content
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();

    }
Clone this wiki locally