java中的进程和线程的问题

进程和线程:

进程是计算机系统资源分配的最小单位,一个进程可以有一个或者多个线程。

线程是计算机运行的最小单位,一个线程只属于一个进程。

一些相关的概念:

单线程:同一个时刻,只允许执行一个线程。

多线程:同一个时刻,可以执行多个线程。

并发和并行:

创建线程的方法: 

Java 提供了三种创建线程的方法:

  • 通过实现 Runnable 接口
  • 通过继承 Thread 类本身;
  • 通过 Callable 和 Future 创建线程。

创建线程的例子:

  • 使用继承Thread来创建线程:

首先是run()方法里面创建一个进程,然后main方法中开了一个主线程,主线程接着开了一个子线程。主线程与子线程的执行是互不影响的。只有所有的线程都结束了进程才结束

public class test_thread extends Thread {

    //主线程:main主线程
    public static void main(String[] args) throws InterruptedException {
        Cat cat = new Cat();
        cat.start();//主线程中又开启了一个子线程

        //主线程开启子线程后,不会阻塞:主线程和子线程会交替执行
        System.out.println("主线程的名字:"+Thread.currentThread().getName());
        for (int i=0;i<10;i++){
            System.out.println("主线程执行 i=" + i);
            Thread.sleep(1000);
        }
    }

}

//业务需求:
//1. 当Cat类继承了 Thread 类, 该类就可以当做线程使用
//2. 我们会重写 run 方法, 写上自己的业务代码
//3. run Thread 类 实现了 Runnable 接口的 run 方法
class Cat extends Thread{
    //创建一个线程,Cat类继承了Thread
    int times=0;

    //创建了一个进程:
    @Override
    public void run() {

        //重写run方法
        while (true){
            System.out.println("喵喵叫。。。。"+(++times) +" "+"子线程名:"+Thread.currentThread().getName());
            //休眠1s
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //如果等于8次,退出循环:
            if (times == 8){
                break;
            }

        }
    }
}

为什么开启子线程需要用start(),而不直接调用run();因为如果直接调用run()方法,此时run()方法就是一个普通的方法。此时的线程就main线程,这时主线程不会开启子线程,只会顺序执行,也就变成了单线程了

public class test_thread02 {
    public static void main(String[] args) throws InterruptedException {

        Dag dag = new Dag();

        dag.run();//这时是执行了一个普通的方法,不会开启一个子线程;这时执行的线程是主线程;

        //此时就变成了单线程了,就是main线程;
        System.out.println("当前的主线程:"+Thread.currentThread().getName());
        for (int i=0;i<9;i++){
            System.out.println("输出i ="+ i );
            Thread.sleep(1000);
        }
    }
}

class Dag extends Thread{
    //创建一个线程,Cat类继承了Thread
    int times=0;

    //创建了一个进程:
    @Override
    public void run() {

        //重写run方法
        while (true){
            System.out.println("喵喵叫。。。。"+(++times) +" "+"子线程名:"+Thread.currentThread().getName());
            //休眠1s
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //如果等于8次,退出循环:
            if (times == 8){
                break;
            }

        }
    }
}
喵喵叫。。。。1 子线程名:main
喵喵叫。。。。2 子线程名:main
喵喵叫。。。。3 子线程名:main
喵喵叫。。。。4 子线程名:main
喵喵叫。。。。5 子线程名:main
喵喵叫。。。。6 子线程名:main
喵喵叫。。。。7 子线程名:main
喵喵叫。。。。8 子线程名:main
当前的主线程:main
输出i =0
输出i =1
输出i =2
输出i =3
输出i =4
输出i =5
输出i =6
输出i =7
输出i =8
  • 实现runnable接口来创建线程:
public class test_runnable {
    public static void main(String[] args) {
        //创建子线程:
        Tiger tiger = new Tiger();
        //因为runnable接口没有start方法:所以需要动态代理的方式:
        Thread thread = new Thread(tiger);
        thread.start();//开启子线程:
        System.out.println("当前主线程的名字是:"+Thread.currentThread().getName());
    }
}

class Tiger implements Runnable{

    //实现了Runnable接口:
    int times=0;
    @Override
    public void run() {
        while (true){
            System.out.println("老虎饿了"+(++times) + " "+"当前的线程名是:"+Thread.currentThread().getName());

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (times == 10){
                break;
            }
        }
    }
}

多线程的使用:

使用实现runnable接口来实现多个线程:

public class test_runnable02 {

    public static void main(String[] args) {
        //开启子线程:
        thread01 thread01 = new thread01();
        thread02 thread02 = new thread02();
        Thread td1 = new Thread(thread01);
        Thread td2 = new Thread(thread02);

        td1.start();
        td2.start();

    }
}


class thread01 implements Runnable{
    //第一个线程

    int count=0;
    @Override
    public void run() {
        while (true){
            System.out.println("hello thread01" + " "+(++count) +" "+ "当前的进程名字是:"+Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (count == 10){
                break;
            }
        }
    }
}

class thread02 implements Runnable{

    int count=0;
    //第二个线程:
    @Override
    public void run() {
        while (true){

            System.out.println("hello thread02" +" "+(++count)+" "+"当前进程名字是:"+ Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (count == 10){
                break;
            }
        }
    }
}
hello thread01 1 当前的进程名字是:Thread-0
hello thread02 1 当前进程名字是:Thread-1
hello thread01 2 当前的进程名字是:Thread-0
hello thread02 2 当前进程名字是:Thread-1
hello thread01 3 当前的进程名字是:Thread-0
hello thread02 3 当前进程名字是:Thread-1
hello thread01 4 当前的进程名字是:Thread-0
hello thread02 4 当前进程名字是:Thread-1
hello thread01 5 当前的进程名字是:Thread-0
hello thread02 5 当前进程名字是:Thread-1
hello thread01 6 当前的进程名字是:Thread-0
hello thread02 6 当前进程名字是:Thread-1
hello thread01 7 当前的进程名字是:Thread-0
hello thread02 7 当前进程名字是:Thread-1
hello thread01 8 当前的进程名字是:Thread-0
hello thread02 8 当前进程名字是:Thread-1
hello thread01 9 当前的进程名字是:Thread-0
hello thread02 9 当前进程名字是:Thread-1
hello thread01 10 当前的进程名字是:Thread-0
hello thread02 10 当前进程名字是:Thread-1

继承Thread和实现Runnable接口的区别:

本质上两者没有区别,但是实现Runnable接口更适合多个线程共享资源,并且避免了单继承的机制。

线程常用的方法:

  • 第一组:

  •  第二组:

守护线程和用户线程:

用户线程:也叫工作线程,当线程的任务执行完后结束;

守护线程:一般是为工作线程服务的。

public class test_Daemon {

    public static void main(String[] args) throws InterruptedException {
        MyDaemon myDaemon = new MyDaemon();
        myDaemon.setDaemon(true);//设置守护线程
        myDaemon.start();
        //执行主线程:
        for (int i=1;i<=10;i++){
            Thread.sleep(1000);
            System.out.println("主线程在执行:"+i+"次");
        }
    }
}

class MyDaemon extends  Thread{

    @Override
    public void run() {

        for (;;){

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("守护线程执行中。。。");
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值