栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

进程与线程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

进程与线程

并行与并发
并行:可以同时进行不同的任务
并发:交替的执行任务
高并发编程的意义、好处和注意事项
多线程:充分利用CPU的资源,加快相应的时间,可以使我们代码模块化、异步化、简单化
OS限制: Linux 1000个 windows 2000个
为什么要限制线程呢:需要分配栈空间
认识java里的线程
Java里的程序天生就是多线程的
几种新启线程的方式
Thread:对线程的抽象
Runnable: 对任务和业务逻辑的抽象

public class NewThread {

    private static class UseThread extends Thread{
        @Override
        public void run() {
            super.run();
            System.out.println("I am extendec Thread");
        }
    }

    public static class UseRunable implements Runnable {
        @Override
        public void run() {
            System.out.println("I am extendec Runnable");
        }
    }

    public static void main(String[] args)
                throws InterruptedException, ExecutionException {
        UseThread useThread=new UseThread();
        useThread.start();

        UseRunable useRunable=new UseRunable();
        new Thread(useRunable).start();
    }
}

关掉线程
stop() : 强制关掉线程,比较野蛮,不建议使用,可能会导致线程所占用的资源不会正常释放。
interrupt():对线程发起一个中断,给线程的一个中断标志位,不代表要立即停止工作,线程可以完全不理会。
isInterrupted():判定是否被中断
interrupted():boolean 静态方法,同样可以检测到中断标志位,但是被调用之后,会把isInterrupted()由true改成false.

private static class UseThread extends Thread{
        @Override
        public void run() {
            super.run();
//            System.out.println("I am extendec Thread");
            String threadName=Thread.currentThread().getName();
            System.out.println(threadName+"interrupt flag"+isInterrupted());
            while (!Thread.interrupted()){
                System.out.println(threadName+"is running");
                System.out.println(threadName+"inner interrupt flag = "+isInterrupted());
            }
            System.out.println(threadName+"interrupt flag"+isInterrupted());
        }
    }

结果:

注意:
jdk里面线程是协作式,而不是抢占式
死锁状态,不会理会中断

线程常用方法和线程的状态
Start和Run方法
start只能调用一次,多次调用会抛出异常。
run可以当成一个普通的方法调用。

public class StartAndRun {
    public static void main(String[] args) {
        ThreadRun threadRun=new ThreadRun();
        threadRun.setName("threadRun");
        threadRun.run();
    }

    public static class ThreadRun extends Thread{
        @Override
        public void run() {
            int i=10;
            while (i>0){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("I am "+Thread.currentThread().getName()+" and now the i="+i--);
            }
        }
    }
}


可以看到调用run的是主线程而不是ThreadRun。
接下来用start方法试试。

public static void main(String[] args) {
        ThreadRun threadRun=new ThreadRun();
        threadRun.setName("threadRun");
        threadRun.start();
    }


可以看到调用的是线程本身。
以上就是start和run方法的最大区别。

了解yield()
yield(): 时间片到期,将线程从运行转为可运行状态。会让出当前cpu的执行权,但是让出的时间不可设定,并且此方法不会释放锁资源。
join():获取执行权,能让线程顺序的执行。可以在需要插队时使用。

线程的优先级

useThread.setPriority(10);
useThread.setPriority(1);

需要休眠或者IO操作的可以把优先级设置的高一些,偏重于计算的可以设置的低一些,确保计算机不会被这些计算把时间占据了…

非守护线程:通过New thread 等手动启动的线程。
守护线程:jdk自己内部或者通过参数配置启动的线程。
守护线程中finally不一定起作用。

synchronized关键字的使用方法

public class SynTest {

    private long count=0;
    private Object obj=new Object();

    public long getCount(){
        return count;
    }

    public  void  setCount(long count){
        this.count=count;
    }

    //用在同步块上
    public void incCount(){
        synchronized (obj){
            count++;
        }
    }

    //用在方法上
    public synchronized void incCount2(){
        count++;
    }

    //count进行累加
    public void incCount3(){
        //this代表SynTest当前对象的实例
        synchronized (this){
            count++;
        }
    }

    private static class Count extends Thread{
        private SynTest simplOper;

        public Count(SynTest simplOper){
            this.simplOper=simplOper;
        }

        @Override
        public void run(){
            for(int i=0;i<10000;i++){
                simplOper.incCount();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException{
        SynTest simplOper=new SynTest();
        //启动两个线程
        Count count1=new Count(simplOper);
        Count count2=new Count(simplOper);
        count1.start();
        count2.start();
        Thread.sleep(50);
        System.out.println(simplOper.count);
    }
}

对象锁:执行某段代码的时候要拿到对象上的锁才能进行,如果有两个对象,每个对象有自己的锁,意味着两个线程可以并行的进行。
类锁:在一个静态方法上面加了一个锁。在打了static方法上进行加锁的话,意味着加锁的是一个class对象,本质上还是对象锁。并不是一个真正存在的东西,和对象锁之间互不干扰。

注意:synchronized锁的是一个具体对象

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/458550.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号