线程各种状态以及方法讲解

线程5大状态 :

 线程常用方法 :

         setPriority(int newPriority)            修改线程的优先级

         static void sleep(long millis)          让当前线程休眠多少毫秒

         void join()                                       等待该线程终止

         static void yield()                            当前线程暂停,其他线程执行

         void interrupt()                                中断线程,别用这个方式

         boolean isAlive()                             测试线程是否处于活动状态

为了防止线程发生异常或者数据混乱,提出以下几个建议
* 1 建议线程正常停止
* 2 可以设置一个标志位,就是循环多少次停止
* 3 不要使用stop或者destroy等过时的方法

线程休眠 :

public class TestThread implements Runnable {

    @Override
    public void run(){
        try {
            Thread.sleep(100);     //线程休眠100毫秒
            System.out.printf(Thread.currentThread().getName());  //打印调用者
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args){
        TestThread t1 = new TestThread();
        new Thread(t1,"张三").start();      //调用线程
        new Thread(t1,"李四").start();       //调用线程
        new Thread(t1,"王五").start();         //调用线程
    }
}

线程礼让 :礼让其他线程先执行

public class TestThread implements Runnable {

    @Override
    public void run(){
        try {
            System.out.printf("我执行的是:"+Thread.currentThread().getName());
            Thread.yield();    //线程礼让,让其他线程先执行
            System.out.printf("礼让后的是:"+Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args){
        TestThread t1 = new TestThread();
        new Thread(t1,"张三").start();
        new Thread(t1,"李四").start();
        new Thread(t1,"王五").start();
    }
}

线程强制执行、插队 :其他线程等待,直到插队线程跑完了其他线程才能继续执行。

public class TestThread implements Runnable {

    @Override
    public void run(){
        try {
            for (int i = 0; i < 10; i++) {
                System.out.printf("我执行的是:"+Thread.currentThread().getName());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        TestThread t1 = new TestThread();
        Thread thread = new Thread(t1);
        thread.start();
        for (int i = 0; i < 200; i++) {
            if(i == 100){
                thread.join();          //插队
            }
            System.out.printf("admin\n");
        }
    }
}

观察线程状态 :

public class TestThread implements Runnable {

    @Override
    public void run(){
        try {
            System.out.printf("线程执行中\n");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        TestThread t1 = new TestThread();       //创建线程
        Thread thread = new Thread(t1);
        thread.start();                         //执行线程
        Thread.State state = thread.getState(); 
        System.out.printf(state+"");            //打印线程状态
        while (state != Thread.State.TERMINATED){//关闭线程、终止线程
            state = thread.getState();
            System.out.printf(state + "");
        }

        thread.start();    //再次调用线程时会抛出异常,因为上面已经关闭了
    }
}

线程优先级 :

public class TestThread implements Runnable {

    @Override
    public void run(){
        try {
            System.out.printf(Thread.currentThread().getName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        TestThread t1 = new TestThread();
        Thread thread = new Thread(t1,"t1");
        thread.start();

        Thread thread2 = new Thread(t1,"t2");
        thread2.setPriority(1);                        //优先级1
        thread2.start();

        Thread thread3 = new Thread(t1,"t3");
        thread3.setPriority(5);                        //优先级5
        thread3.start();

        Thread thread4 = new Thread(t1,"t4");
        thread4.setPriority(10);                        //优先级10
        thread4.start();
    }
}

守护线程 :

        用户线程 :用户线程是程序正常线程,他执行完了就自动停止了,可以人为的干预他执行。

        守护线程 :就好比我们的java垃圾回收机制,他守护我们的程序执行。(操作日志、内存监控等等)。

线程不安全 :

//这是一个不安全的线程,模拟3个人同时强10张票的场景
public class TestThread implements Runnable {

    int number = 10;
    boolean flag = true;

    @Override
    public void run(){
        try {
            Thread.sleep(100);
            while (flag){
                System.out.printf(Thread.currentThread().getName()+"买到了第"+number+"张票\n");
                number--;
                flag = number > 0 ? flag : !flag;          //如果票不足了就不让他们买了
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        TestThread t1 = new TestThread();
        Thread thread = new Thread(t1,"t1");
        thread.start();

        Thread thread2 = new Thread(t1,"t2");
        thread2.setPriority(1);
        thread2.start();

        Thread thread3 = new Thread(t1,"t3");
        thread3.setPriority(5);
        thread3.start();

        Thread thread4 = new Thread(t1,"t4");
        thread4.setPriority(10);
        thread4.start();
    }
}

  每个线程在自己的工作内存交互,内存控制不当会导致数据不一致

t4买到了第10张票
t1买到了第10张票
t1买到了第8张票
t1买到了第7张票
t1买到了第6张票
t1买到了第5张票
t1买到了第4张票
t1买到了第3张票
t1买到了第2张票
t1买到了第1张票
t3买到了第10张票
t4买到了第9张票
t3买到了第-1张票                      多个线程同时执行出现不安全的情况
t3买到了第-3张票                      多个线程同时执行出现不安全的情况

提示 : new ArrayList<>() 线程是不安全的,为什么呢?因为如果多个线程去同时操作他的话他的数据会不一致,丢失或缺少。类似下面这段代码。

用下面的synchronized可以保证list安全 :

synchronized同步方法,保证线程安全 :

public class TestThread implements Runnable {

    int number = 10;
    boolean flag = true;

    @Override
    public void run(){
        try {
            buyATicket();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public synchronized void buyATicket(){//synchronized 同步方法,可以保证我们的线程安全,就是每个人都得排队
        while (flag){
            System.out.printf(Thread.currentThread().getName()+"买到了第"+number+"张票\n");
            number--;
            flag = number > 0 ? flag : !flag;          //如果票不足了就不让他们买了
        }
    }

    public static void main(String[] args) throws InterruptedException {
        TestThread t1 = new TestThread();
        Thread thread = new Thread(t1,"t1");
        thread.start();

        Thread thread2 = new Thread(t1,"t2");
        thread2.setPriority(1);
        thread2.start();

        Thread thread3 = new Thread(t1,"t3");
        thread3.setPriority(5);
        thread3.start();

        Thread thread4 = new Thread(t1,"t4");
        thread4.setPriority(10);
        thread4.start();
    }
}


输出结果正常 :
t4买到了第10张票
t4买到了第9张票
t4买到了第8张票
t4买到了第7张票
t4买到了第6张票
t4买到了第5张票
t4买到了第4张票
t4买到了第3张票
t4买到了第2张票
t4买到了第1张票

进程已结束,退出代码为 0

synchronized 同步块 :锁的对象就是需要变化的量,就是要对我们对象进行增删改查操作的。

public class TestThread implements Runnable {

    boolean flag = true;
    Account account = new Account();

    @Override
    public void run(){
        try {
            buyATicket();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void buyATicket(){
        synchronized(account){  //同步块,多个线程操作这个块,我们让操作这个对象的线程排队执行
            while (flag){
                System.out.printf(Thread.currentThread().getName()+"买到了第"+account.number+"张票\n");
                account.number--;
                flag = account.number > 0 ? flag : !flag;  //如果票不足了就不让他们买了
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        TestThread t1 = new TestThread();
        Thread thread = new Thread(t1,"t1");
        thread.start();

        Thread thread2 = new Thread(t1,"t2");
        thread2.setPriority(1);
        thread2.start();

        Thread thread3 = new Thread(t1,"t3");
        thread3.setPriority(5);
        thread3.start();

        Thread thread4 = new Thread(t1,"t4");
        thread4.setPriority(10);
        thread4.start();
    }

    class Account{
        int number = 10;
    }
}

提示 : synchronized虽然可以防止我们线程发生数据混乱,保证数据的一致性,但是我们在开发过程中也需要防止死锁,避免多个方法操作并死锁同一段代码。

Lock锁 :

        

public class TestThread implements Runnable {

    boolean flag = true;
    Account account = new Account();
    private final ReentrantLock locks = new ReentrantLock();   //定义锁

    @Override
    public void run() {
        try {
            //noinspection AlibabaLockShouldWithTryFinally
            locks.lock();                //对方法加锁
            buyATicket();
        } finally {
            locks.unlock();                 //对方法解锁
        }
    }

    public void buyATicket() {
        while (flag) {
            System.out.printf(Thread.currentThread().getName() + "买到了第" + account.number + "张票\n");
            account.number--;
            flag = account.number > 0 ? flag : !flag;  //如果票不足了就不让他们买了
        }
    }

    public static void main(String[] args) throws InterruptedException {
        TestThread t1 = new TestThread();
        Thread thread = new Thread(t1,"t1");
        thread.start();

        Thread thread2 = new Thread(t1,"t2");
        thread2.setPriority(1);
        thread2.start();

        Thread thread3 = new Thread(t1,"t3");
        thread3.setPriority(5);
        thread3.start();

        Thread thread4 = new Thread(t1,"t4");
        thread4.setPriority(10);
        thread4.start();
    }
    class Account{
        int number = 10;
    }
}

线程池 :

public class TestThread implements Runnable {
    String name;
    public TestThread(String names){
        this.name=names;
    }
    @Override
    public void run() {
        System.out.printf(name+"\n");
    }


    public static void main(String[] args) throws InterruptedException {
        //创建一个线程池,线程数2个
        ExecutorService service;
        service = Executors.newFixedThreadPool(2);
        //放入4个数据到线程池里面并传入名字
        service.execute(new TestThread("11"));
        service.execute(new TestThread("22"));
        service.execute(new TestThread("33"));
        service.execute(new TestThread("44"));
        //关闭连接
        service.shutdown();
    }

}

输出
11
33
44
22

进程已结束,退出代码为 0

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值