Java多线程(一)

一、创建线程的两种方式

1、继承Thread类

public class MyThreadClass extends Thread {
    @Override
    public void run() {
        System.out.println("MyThreadClass ...");
    }
}

2、实现Runnable接口,重写run方法

public class MyThreadInterface implements Runnable{
    @Override
    public void run() {
        System.out.println("MyThreadInterface ...");
    }
}

二、启动线程

Thread类的构造方法蛮多,下面是几个比较常用的。

public Thread() {
    init(null, null, "Thread-" + nextThreadNum(), 0);
}

//Thread类实现Runnable接口,这里也可以传入Thread的子类
public Thread(Runnable target) {
    init(null, target, "Thread-" + nextThreadNum(), 0);
}
//name为线程名称
public Thread(Runnable target, String name) {
    init(null, target, name, 0);
}

通过一定要通过start()方法启动线程,如果通过run()方法启动,就变成同步执行了。

public static void main(String[] args) {
        MyThreadClass t1 = new MyThreadClass();
        t1.start();

        Thread t2 = new Thread(new MyThreadInterface());
        t2.start();
        
        Thread t3 = new Thread(new MyThreadClass());
        t3.start();
    }

三、几个常用的方法

currentThread() //当前线程

isAlive() //判断当前线程是否处于激活状态

sleep() //线程休眠,单位秒

getId() //线程的ID

下面一段代码,运用了上面几个方法:

public static void main(String[] args) {
        try {
            MyThreadClass t1 = new MyThreadClass();
            Thread t2 = new Thread(new MyThreadInterface());
            Thread t3 = new Thread(new MyThreadClass());
            t1.start();
            Thread.sleep(1000);  //1
            t2.start();
            System.out.println("t2's id is : " + t2.getId()); //2
            t3.start();
            System.out.println("t3's id is : " + t3.getId());
            System.out.println("thread t1 is alive: " + t1.isAlive());
            System.out.println("thread " + Thread.currentThread().getName() //3
                    + " is alive: " + Thread.currentThread().isAlive());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

注释解释:

1、 Thread.sleep(1000);当前正在运行的线程休眠1s,上述即main线程休眠1s钟

2、取得当前线程的唯一ID

3、当前正在运行的是main线程,所以main线程是激活状态,而t1线程已经执行完,所以t1线程不是激活状态

运行结果

   

四、停止线程

停止线程的三种方式:

1、使用退出标志,使线程正常退出,即run()方法执行完后线程终止

2、使用stop方法强行停止线程,目前已经作废,不讨论了

3、使用interrupt()方法改变正在运行的线程状态,同时需要在线程中根据线程状态,来终止线程

(换个说法,给这个线程打个标记,告诉他自己,你要废了,他自己获取到这个标记后,喝点敌敌畏,直接挂了)

这里主要看第3种方式如何实现停止线程的。说到停止线程,就不得不说的两个方法interrupted()和isInterrupted().

对比:

interrupted()静态方法

测试当前线程是否为中断状态,执行后,将状态标志更改为false,即执行后,线程就不是中断状态了。

isInterrupted()实例方法

仅测试线程是否为中断状态,不更改状态标志

public static void main(String[] args) {
    Thread.currentThread().interrupt();
    System.out.println(Thread.interrupted());  //true
    System.out.println(Thread.interrupted());  //false

    Thread.currentThread().interrupt();
    System.out.println(Thread.currentThread().isInterrupted()); //true
    System.out.println(Thread.currentThread().isInterrupted()); //true
}

上述第3种方法主要有两个步骤:

1、通过interrupt()方法给正在运行的线程打上中断标记

2、线程内部根据标记来自行停止

package hccool;

/**
 * @author hgh
 * @Package hccool
 * @createDate 2020/04/27 14:14
 */
public class TestInterruptMethod {

    public static void main(String[] args) {

        try {
            InterruptMethodManager thread = new InterruptMethodManager();
            thread.start();
            Thread.sleep(1000);
            thread.interrupt(); //在线程启动1s后给其打了个残废标记
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    static class InterruptMethodManager extends Thread {

        @Override
        public void run() {
            for (int i = 0; i < 30 * 10000; i++) {
                //判断当前是否打了终止标记。如果是,通过抛异常退出(有其他种方式终止,建议抛异常的方式)
                if (this.isInterrupted()) {
                    throw new RuntimeException("stop thread success!");
                }
                System.out.println("current i is :" + i);
            }
            System.out.println("如果线程成功终止,那么这句话不会被输出...");
        }
    }
}

控制台输出的结果如下,线程成功终止停下来了。

五、线程的优先级

几个特性:

    1、继承性(传递)

          A线程启动B线程,则B线程的优先级与A保持一致

    2、规则性

          高优先级的线程总是大部分先执行完,但不是全部先执行完

    3、随机性

          高优先级的线程总是大部分先执行完,但不是全部先执行完,剩下那部分屌丝逆袭成功的就代表了随机性

 

package hccool;

/**
 * @author hgh
 * @Package hccool
 * @createDate 2020/04/27 14:38
 */
public class TestPriority {

    public static void main (String[] args){
        ThreadA a = new ThreadA();
        ThreadB b = new ThreadB();

        a.setPriority(Thread.MAX_PRIORITY);
        b.setPriority(Thread.MIN_PRIORITY);

        a.start();
        b.start();
    }

    static class ThreadA extends Thread {
        @Override
        public void run() {
            ThreadC c = new ThreadC();
            c.start();
            for (int i = 0; i < 100; i++) {
                System.out.println("ThreadA: " + i);
            }
        }
    }

    static class ThreadB extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                System.out.println("ThreadB: " + i);
            }
        }
    }

    static class ThreadC extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                System.out.println("ThreadC: " + i);
            }
        }
    }
}

每次运行的结果都不一致,但总体来说threadA 和 threadC优先threadB输出。

这一篇先这样咯~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值