进程与线程

并行与并发
并行:可以同时进行不同的任务
并发:交替的执行任务
高并发编程的意义、好处和注意事项
多线程:充分利用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锁的是一个具体对象

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值