一、多线程基础概念、实现线程三种方法、中断线程方法,以及线程状态转化

注:本博客原始资料来自于享学课堂

1、CPU核心数和线程数的关系

1:1的关系,引入超线程之后,就是1:2

2、cpu时间轮转机制,即RR调度

3、进程和线程

进程:程序运行资源分配最小单位,进程内部有多个线程,多个线程之间会共享进程资源

线程:CPU调度的最小单位

4、并行和并发

并行:同一时刻可以处理的事情

并发:同一时间段可以处理的事情

5、高并发编程的意义、好处和注意事项

1、可以充分利用CPU的资源

2、加快响应用户的时间

共享资源,就能存在冲突;

如果多线程控制不好,可能会存在死锁;

线程太多,搞垮机器,或内存溢出;

 

java当中的线程,一个简单的main函数至少运行五个线程

public class OnlyMain {
    public static void main(String[] args) {
        //虚拟机线程管理的接口
        ThreadMXBean bean = ManagementFactory.getThreadMXBean();
        ThreadInfo[] dumpAllThreads = bean.dumpAllThreads(false, false);
        for(ThreadInfo temp : dumpAllThreads) {
            System.out.println("[id:"+temp.getThreadId()+"]"+"  name:"+temp.getThreadName());
        }
    }
}

得到的结果如下

[id:5]  name:Attach Listener
[id:4]  name:Signal Dispatcher
[id:3]  name:Finalizer                //释放内存的,虚拟机不保证一定会执行
[id:2]  name:Reference Handler
[id:1]  name:main

java中启动线程的方式:

1、继承Thread

2、实现Runnable接口

3、接口Callable

如下是三种方法的简单实用实例:

public class TestThread {
    private static class FirstThread extends Thread{
        public void run() {
            {
                System.out.println("thread");
            }
        }
    }
    private static class runThread implements Runnable{
        @Override
        public void run() {
            System.out.println("run");
        }
    }
    private static class CallThread implements Callable<String>{
        @Override
        public String call() throws Exception {
            return "call";
        }
    }
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        new Thread(new FirstThread()).start();
        new Thread(new runThread()).start();
        
        CallThread callThread = new CallThread();
        //FutureTask实现了Runnable接口的,所以这样封装之后就可以使用
        FutureTask<String> futureTask = new FutureTask<>(callThread);
        new Thread(futureTask).start();

        //获取callable返回的值,同时这里的get方法是阻塞的
        System.out.println(futureTask.get());
    }
}

让线程停止工作的方法:

1、自然执行完;

2、抛出异常;

3、stop():结束线程的时候,无法保证资源是释放的,已经被废弃;

4、resume():无法保证资源是释放的,已经被废弃;

5、suspend():挂起,调用之后线程不会释放资源的,可能会导致死锁等问题;已经废弃;

现在使用以下方法:

6、interrupt() :中断一个线程,并不是强行关闭,而是打个招呼,是否中断由线程自己决定,中断标志位=true

7、 isInterrupted():判断当前线程是否处于中断状态

8static方法interrupted():判断单签线程是否处于中断状态,和7不同的是,他会修改中断标志位=false

Thread:

public class EndThread {
    private static class UseThread extends Thread {
        public UseThread(String name) {
            super(name);
        }
        @Override
        public void run() {
            String currentName = Thread.currentThread()
                    .getName();
            while (
!isInterrupted()) {
                System.out.println(currentName + " is running!");
            }
            System.out.println(currentName + " is stoped!");
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new UseThread("endThread");
        thread.start();
        Thread.sleep(10);
        thread.interrupt();
    }
}

运行结果:

endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is stoped!

Runnable:

public class EndRunnable {

    private static class UseRunnable implements Runnable {
        @Override
        public void run() {
            String currentName = Thread.currentThread().getName();
          
 while (!Thread.currentThread().isInterrupted()) {
                System.out.println(currentName + " is running!");
            }
            System.out.println(currentName + " is stoped!");
        }
    }
    public static void main(String[] args) throws InterruptedException {
        UseRunnable useRunnable = new UseRunnable();
        Thread thread = new Thread(useRunnable,"endThread");
        thread.start();
        Thread.sleep(10);
        thread.interrupt();
    }
}

运行结果:

endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is running!
endThread is stoped!

callable:

抛出InterruptedException异常的处理:

public class EndRunnable {

    private static class UseRunnable implements Runnable {
        @Override
        public void run() {
            String currentName = Thread.currentThread().getName();
            while (!Thread.currentThread().isInterrupted()) {
                
try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println(currentName + "-"+Thread.currentThread().isInterrupted());
            }
            System.out.println(currentName + " is stoped!--"+Thread.currentThread().isInterrupted());
        }
    }
    public static void main(String[] args) throws InterruptedException {
        UseRunnable useRunnable = new UseRunnable();
        Thread thread = new Thread(useRunnable,"endThread");
        thread.start();
        Thread.sleep(10);
        thread.interrupt();
    }
}

方法里如果抛出InterruptedException,线程的中断标志位会被复位成false,如果确实是需要中断线程,要求我们自己在catch语句块里再次调用interrupt()。

运行结果:

java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at multcurrent.EndRunnable$UseRunnable.run(EndRunnable.java:25)
    at java.lang.Thread.run(Unknown Source)
endThread-false
endThread-false
endThread-false
endThread-false
endThread-false

。。。

中断线程的使用误区

有些人在中断线程的时候,不使用isInterrupted判断线程是否中断,而是自己定义一个布尔变量来判断,如下:

    private static class UseRunnable implements Runnable {
        private volatile boolean
cancel = false;
        
        public void cancel() {
            cancel = true;
        }
        @Override
        public void run() {
            while (
cancel) {
            }
        }
    }

这个时候,如果线程当中的代码发生了阻塞,cancel的变化会改变的不及时,可能带来未知的问题;此时可以将while(true)改为while(true || isInterrupted),才是最为保险的!

线程的状态转换:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值