5、进程与线程

本文详细介绍了进程与线程的概念及应用,包括线程的创建、启动方式、生命周期状态及同步机制等内容。并通过实例对比了继承Thread类与实现Runnable接口的不同之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

进程与线程

1、  进程是程序的一次动态执行过程,它经历了从代码加载、执行到执行完毕的一个完整过程,这个过程也是进程本身从产生、发展到消亡的过程

2、  线程Thread是进程下更小的执行单位,同一进程下的多个线程可以同时执行,叫多线程

 

 

线程的使用

1、  线程可以通过继承Thread类或Runnable接口来实现,线程启动后会默认调用类中的run方法,如下

class MyThread extends Thread{

    private String name;

    public MyThread(String name){

        this.name = name;

    }

    //线程默认调用的方法

    publicvoid run(){

        for(int i=1; i<=10; i++){

            System.out.println(this.name +": "+ i);

        }

    }

}

 

2、  使用Thread定义线程,并使用

class MyThread extends Thread{

    private String name;

    public MyThread(String name){

        this.name = name;

    }

    publicvoid run(){

        for(int i=1; i<=10; i++){

            System.out.println(this.name +": "+ i);

        }

    }

}

 

publicclass hello{

    publicstaticvoid main(String args[]){

        MyThread t1 =new MyThread("thread one");

        MyThread t2 =new MyThread("thread two");

        t1.run();

        t2.run();

    }

}

执行后发现,程序在按顺序执行,显然多线程并没有启动。要启动线程,需要将t1.run()与t2.run()修改为t1.start()和t2.start()才可以,start表示启动线程,而线程启动后会直接去调用类中的run()方法。

 

3、  使用Runnable定义线程,并使用

class MyThread implements Runnable{

    private String name;

    public MyThread(String name){

        this.name = name;

    }

    publicvoid run(){

        for(int i=1; i<=10; i++){

            System.out.println(this.name +": "+ i);

        }

    }

}

 

publicclass hello{

    publicstaticvoid main(String args[]){

        MyThread t1 =new MyThread("thread one");

        MyThread t2 =new MyThread("thread two");

        Thread td1 =new Thread(t1);     //启动仍需通过Thread对象

        Thread td2 =new Thread(t2); //启动仍需通过Thread对象

        td1.start();

        td2.start();

    }

}

Runnable接口定义的线程如果要启动仍然需要通过Thread对象,这是主要的区别

 

4、  Thread类与Runable接口的区别

一个类如果继承了Thread类,则多线程不适合进行资源共享;而实现了Runnable接口则可以方便的实现资源共享

可以通过Thread.currentThread().getName()获取当前线程对象和线程名称

 

继承Thread类如下,共5张票,但是每个线程都卖出了5张票,这是不对的

class MyThread extends Thread{

    privateint ticket =5;

    publicvoid run(){

        for(int i=1; i<100; i++){

            if(ticket>0){

                System.out.println(Thread.currentThread().getName()

 +" sold ticket: "+ ticket--);

            }

        }

    }

}

 

publicclass hello{

    publicstaticvoid main(String args[]){

        //声明了两个线程对象,两个线程都拥有自己单独的资源

        MyThread t1 =new MyThread();

        MyThread t2 =new MyThread();

        //分别启动两个线程,因为两个线程的资源不是共享的

        //所以每个线程会发5张票,这就不对了

        t1.start();

        t2.start();

    }

}

 

实现Runnable接口的类如下,共5张票,两个线程共输出5张票,结果正确

通过Thread.currentThread()可获取当前线程对象

通过Thread.currentThread().getName()可以获取当前线程对象名

class MyThread implements Runnable{

    privateint ticket =5;

    publicvoid run(){

        for(int i=1; i<100; i++){

            if(ticket>0){

                System.out.println(Thread.currentThread().getName()

 +" sold ticket: "+ ticket--);

            }

        }

    }

}

 

publicclass hello{

    publicstaticvoid main(String args[]){

        //声明一个资源对象

        MyThread t1 =new MyThread();

        //启动两个线程,两个线程共享t1内的资源,实现资源共享

        Thread td1 =new Thread(t1);

        Thread td2 =new Thread(t1);

        td1.start();

        td2.start();

    }

}

 

 

JVM、进程与线程

1、  Java编写的程序都运行在jvm中,每一个程序启动时,都会启动一个JVM,这个JVM实际上就是进程

2、  一个java程序至少启动两个线程,一个是main函数线程,一个是程序的垃圾收集线程

 

 

线程状态

1、  创建:Thread t =new Thread();

2、  就绪:t.start();线程启动后就进入操作系统排队,排到了就调用run方法运行

3、  运行:t.run(); 由系统调用运行

4、  堵塞:sleep();suspend();wait()时,线程暂停执行

5、  死亡:stop()或run()结束时

 

 

线程同步与死锁

1、  实现了Runnable接口的类,类中的属性由多个线程共享,这时如果多个线程同时操作一个资源时就会出问题,所以出现了线程同步问题,如下

class MyThread implements Runnable{

    privateint ticket =5;

    publicvoid run(){

        for(int i=1; i<100; i++){

            if(ticket>0){

                try{

                    //sleep后线程紧密排队,导致资源争抢

                    Thread.sleep(300);

                }catch(Exception ex){

                    ex.printStackTrace();

                }

                System.out.println(Thread.currentThread().getName()+" sold ticket: "+ ticket--);

            }

        }

    }

}

 

publicclass hello{

    publicstaticvoid main(String args[]){

        MyThread t1 =new MyThread();

        Thread td1 =new Thread(t1);

        Thread td2 =new Thread(t1);

        td1.start();

        td2.start();

    }

}

 

2、  线程同步,指同一时间内,只允许一个线程对资源进行操作,其它线程排队直到前一个线程完成

 

3、  同步代码块,synchronized(同步对象){需同步代码},如下

class MyThread implements Runnable{

    privateint ticket =5;

    publicvoid run(){

        for(int i=1; i<100; i++){

            //同步其中的代码块,防止资源争抢,一般使用this,意思是对当前对象进行同步

            //同一时间只允许一个线程访问this(当前)对象,而this对象中包含共享资源ticket

            synchronized(this){

                if(ticket>0){

                    try{

                        Thread.sleep(300);

                    }catch(Exception ex){

                        ex.printStackTrace();

                    }

                    System.out.println(Thread.currentThread().getName()+" sold ticket: "+ ticket--);

                }

            }

        }

    }

}

 

4、  同步方法,锁定了该方法同一时间只能有一个线程对其进行调用,如下

class MyThread implements Runnable{

    privateint ticket =5;

    publicvoid run(){

        for(int i=1; i<100; i++){

            sale();

        }

    }

    //同步方法,

    privatesynchronizedvoid sale(){

        if(ticket>0){

            try{

                Thread.sleep(300);

            }catch(Exception ex){

                ex.printStackTrace();

            }

            System.out.println(Thread.currentThread().getName()+" sold ticket : "+ ticket--);

        }

    }

}

 

 

同步与死锁

1、  当需要解决资源共享时,要使用同步来解决

2、  当同步过多时,会出现死锁问题

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值