Java线程理解

线程的概念

线程也被称为轻型进程,而我觉得线程是一个带有入口的方法,必须来通过入口进行调用线程。(个人理解,不喜勿喷)

线程的创建

创建线程有两种方法,一是继承Thread,二是实现Runnable接口

首先介绍继承Thread 来创建线程,

Demo:

class add extends Thread{

    public void run(){

        int i;

        for(i=0;i<2;i++)

            System.out.println("Thread :"+i);

    }

    public static void main(String[]args){

        int i;

        add a=new add();

        a.start();

        }

    }

}

第二种创建线程的方法:实现Runnable

Demo:

class add implements Runnable{

    public void run(){

        int i;

        for(i=0;i<2;i++)

            System.out.println("Thread :"+i);

    }

    public static void main(String[]args){

        int i;

        add a=new add();

        new Thread(a).start();

    }

}

线程的生命周期及调度

我查了网上好多的博客,各有各的说法,不过一般都是4个或5个,而且生命周期的说法不同,但英文是一样的,我就用书上看到的说法,分别是创建(new),就绪(runnable),运行(Running),阻塞(blocked),死亡(dead),5个生命状态。

1.     创建(new)

当用new 创建线程对象实例后,它作为一个实例存在,JVM并没有为其分配CPU时间片等资源

2.     就绪(runnable)

对创建(new)状态的线程调用start方法转换为就绪状态(runnable),线程获得除CPU时间片外的系统资源,等JVM的线程调度器按照线程优先级调度,从而使线程获得CPU时间片。运行状态的线程可以使用yield方法使线程进入就绪状态

3.     运行(Running)

线程获得CPU时间片后进入运行状态,运行run方法里的程序。

4.     阻塞(blocked)

阻塞指的是暂停一个线程来等待某个条件的发生(某资源的调度),调度机制不分给它任何CPU时间,直接跳过

5.     死亡(dead)

线程体运行结束或调用stop方法,线程终止,有JVM收回线程占用的资源。

   (sleep,suspend,wait方法的区别

sleep ()使当前线程在指定的时间处于“非运行”(Not Runnable)状态。线程一直持有对象的监视器。比如一个线程当前在一个同步块或同步方法中,其它线程不能进入该块或方法中。如果另一线程调用了 interrupt ()方法,它将唤醒那个“睡眠的”线程。
注意:sleep ()是一个静态方法。这意味着只对当前线程有效,一个常见的错误是调用t.sleep (),(这里的t是一个不同于当前线程的线程)。即便是执行t.sleep (),也是当前线程进入睡眠,而不是t线程。

suspend ()是过时的方法,使用 suspend ()导致线程进入停滞状态,该线程会一直持有对象的监视器,suspend ()容易引起死锁问题。

wait ()使当前线程出于“不可运行”状态,和 sleep ()不同的是wait 是 object 的方法而不是 thread。调用 object.wait ()时,线程先要获取这个对象的对象锁,当前线程必须在锁对象保持同步,把当前线程添加到等待队列中,随后另一线程可以同步同一个对象锁来调用 object.notify (),这样将唤醒原来等待中的线程,然后释放该锁。基本上wait ()/notify ()与 sleep ()/interrupt ()类似,只是前者需要获取对象锁。

   线程的调度

     系统中只有1个CPU时以某种顺序在单CPU情况下执行多线程叫做调度。

     JAVA采用了固定优先级调度的方法。该算法根据处于可运行态线程的优先级实行调度。

     JAVA优先级分10个等级,分别用1到10数字表示

     而设计优先级的方法为:thread.setPriority(int);

线程的互斥

假设银行总共有100元;而在2个窗口中同时有2个人来取100元;从道理来说,只能一个人取到,另一个人取不到,用线程来看:

Demo:

class add extends Thread{

    static int count=100;

    public void run(){

        if(count>0){

            try{

                System.out.println("withdraw 100 success!");

                count-=100;

                System.out.println("count :"+count);

            }catch(Exception e){

                e.printStackTrace();

            }

        }

        else {

            System.out.println("failed to withdraw");

        }

    }

    public static void main(String[]args){

        add t1=new add();

        add t2=new add();

        t1.start();

        t2.start();

    }

}

然而结果却是:

withdraw100 success!

withdraw100 success!

count:0

count :-100

2个人都取出来了,银行总款为-100。线程t1在满足条件后,就被线程2打断,导致线程t2也进入判断的语句,从而导致2人都判定总额count大于0;这就是线程的互斥现象。

对于此问题,JAVA提供了一个互斥锁的机制,关键字synchronized;基本用法如下:

synchronized(互斥对象){

   代码段

}

Demo:

class add extends Thread{

    static int count=100;

    public void run(){

        synchronized (this)

        {

            if(count>0){

                try{

                    System.out.println("withdraw 100 success!");

                    count-=100;

                    System.out.println("count :"+count);

                }catch(Exception e){

                    e.printStackTrace();

                }

            }

            else {

                System.out.println("failed to withdraw");

            }

        }

    }

    public static void main(String[]args){

        add t1=new add();

        add t2=new add();

        t1.start();

        t2.start();

    }

}

输出结果为:

withdraw100 success!

count:0

failed towithdraw

当线程t1检测synchronized代码段后,发现没有其他线程进入互斥锁中,线程t1获得该互斥锁,执行synchronized代码段,直到执行完毕释放互斥锁,当线程2发现其他线程拥有互斥锁执行代码时,会自动进入该互斥对象的等候队列,等待其他线程释放互斥锁。

synchronized 也可以用于方法前面,用法;public synchronized void withdraw()

它以该方法所在的对象为互斥对象,故不需要明确指明互斥对象

关于线程的同步,线程死锁以及线程池的内容,稍后更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值