并发-2-Thread和Runnable的API

创建线程的两种方式:

1.继承Thread,重写run方法,使用start()使用线程 

2.将Runnable作为Thread的构造参数
复制代码
public class ThreadCreate {
    public static void main(String[] args) {
        System.out.println("主线程ID:" + Thread.currentThread().getId());

        /**
         * 第一种创建线程的方式
         */
        Thread firstMethod2CreateThread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("子线程ID:" + Thread.currentThread().getId());
            }
        });
        firstMethod2CreateThread.start();

        /**
         * 第二种创建线程的方式
         */
        class SecondMethod2CreateThread extends Thread {
            @Override
            public void run() {
                System.out.println("子线程ID:" + Thread.currentThread().getId());
            }
        }
        SecondMethod2CreateThread secondMethod2CreateThread = new SecondMethod2CreateThread();
        secondMethod2CreateThread.start();
    }
}
复制代码

Thread类详解:

JAVA中多线程的核心是Thread,Thread翻译为线程,线程有以下几种状态,接下来我会按照Thread类中的方法来逐一讲解。
复制代码

1.Thread t = new Thread()仅仅只是创建了线程,并没有为线程分配任何资源
2.start()方法用来启动线程,为相应地线程分配资源,分配到资源才能参与到竞争CPU的过程中 run():当start()启动一个线程后,线程一直等待直到获得了CPU执行时间,就进入run方法体

3.sleep()让线程休眠,主动让出CPU,但是不会释放锁,休眠时间满后,不一定立即得到执行,还需要重新参与竞争排队

public class ThreadSleep {

    private int i = 0;
    public Object lock = new Object();

    public static void main(String[] args) {
        ThreadSleep mh = new ThreadSleep();
        ThreadTest tt = mh.new ThreadTest();
        ThreadTest tt2 = mh.new ThreadTest();
        tt.start();
        tt2.start();
    }

    class ThreadTest extends Thread {
        @Override
        public void run() {
            //使用的锁为Object lock = new Object(); 而不是方法所在的类的内置monitor
            synchronized (lock) {
                i++;
                System.out.println("i:" + i);
                try {
                    System.out.println("线程i:" + Thread.currentThread().getId() + "睡眠开始");
                    long startTime = System.currentTimeMillis();
                    Thread.currentThread().sleep(1000);
                    long endTime = System.currentTimeMillis();
                    System.out.println("线程i:" + Thread.currentThread().getId() + "睡眠时间:" + (endTime - startTime));
                } catch (Exception e) {
                } finally {
                    System.out.println("线程i:" + Thread.currentThread().getId() + "睡眠结束");
                }
                i++;
                System.out.println("i:" + i);
            }
        }
    }
}
复制代码

输出:

i:1
线程i:9睡眠开始
线程i:9睡眠时间:1005
线程i:9睡眠结束
i:2
i:3
线程i:10睡眠开始
线程i:10睡眠时间:1004
线程i:10睡眠结束
i:4
复制代码

4.yield()使线程让出CPU去执行相同优先级的其他程序,但是不会释放锁,(内部还是sleep)执行yield()之后该线程直接进入就绪状态再次参与竞争,生产中很少使用。

5.A线程的run()中调用了B线程的join(),则A线程等待B线程执行完之后,再继续执行,实际上调用了Object类中的wait()方法,会释放锁

public class ThreadJoin {

    public static void main(String[] args) throws IOException {
        System.out.println("进入线程"+Thread.currentThread().getName());
        ThreadJoin test = new ThreadJoin();
        MyThread thread1 = test.new MyThread();
        thread1.start();
        try {
            System.out.println("线程"+Thread.currentThread().getName()+"等待");
            thread1.join();
            System.out.println("线程"+Thread.currentThread().getName()+"继续执行");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    class MyThread extends Thread{
        @Override
        public void run() {
            System.out.println("进入线程"+Thread.currentThread().getName());
            try {
                Thread.currentThread().sleep(5000);
            } catch (InterruptedException e) {
                // TODO: handle exception
            }
            System.out.println("线程"+Thread.currentThread().getName()+"执行完毕");
        }
    }
}
复制代码

输出:

进入线程main
线程main等待
进入线程Thread-0
线程Thread-0执行完毕
线程main继续执行
复制代码

6.interrupt()使得处于阻塞状态的线程抛出一个异常,也就是说,它可以中断并且只能中断一个处于阻塞状态的线程

public class ThreadInterrput {

    public static void main(String[] args) {
        ThreadInterrput mh = new ThreadInterrput();
        ThreadTest tt = mh.new ThreadTest();
        tt.start();
        try {
            Thread.currentThread().sleep(2000);
        } catch (InterruptedException e) {
        }
        tt.interrupt();
    }

    class ThreadTest extends Thread {
        @Override
        public void run() {
            try {
                System.out.println("子线程睡眠开始");
                Thread.currentThread().sleep(10000);
                System.out.println("子线程睡眠结束");
            } catch (InterruptedException e) {
                System.out.println("子线程获取到中断");
            }
            System.out.println("run执行完毕");
        }
    }
}
复制代码

输出:

子线程睡眠开始
子线程获取到中断
run执行完毕
复制代码

7.开发中一般不使用interrupt()而在类中增加isStop属性来标志是否结束while循环

class MyThread extends Thread{
        private volatile boolean isStop = false;
        @Override
        public void run() {
            int i = 0;
            while(!isStop){
                i++;
            }
        }
         
        public void setStop(boolean stop){
            this.isStop = stop;
        }
    }
复制代码

这样一来便可在线程外通过调用setStop方法来终止while循环。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值