美文网首页
多线程基础(二)

多线程基础(二)

作者: Maxinxx | 来源:发表于2019-03-06 21:31 被阅读0次
如何实现多线程程序?

由于线程是依赖进程而存在的,所以应该先创建一个进程出来。而进程是由系统创建的,所以我们应该去调用系统功能创建一个进程。Java是不能直接调用系统功能的,所以,我们没有办法直接实现多线程程序。但是,java可以去调用c/c++写好的程序来实现多线程程序。由c/c++去调用系统功能创建进程,然后由java去调用这样的东西,然后提供一些类供我们使用。我们就可以实现多线程程序了。

有两种方式可以实现多线程程序
方式1:继承Thread类。
方式2:实现Runnable接口。方式2实现请点击链接。https://www.jianshu.com/p/0dcd56c71231

一、Thread类

步骤

  • 自定义类MyThread继承Thread类。
  • MyThread类里面重写run()?
    问题:为什么是run()方法呢?
    答:不是类中的所有代码都需要被线程执行的,而这个时候,为了区分哪些代码能够被线程执行,java提供了Thread类中的run()用来包含哪些被线程执行的代码。
  • 创建对象
  • 启动线程

二、多线程的代码实现、获取和设置线程名称的办法

1 定义MyThread类、重写run()方法

public class MyThread extends Thread {
    public MyThread() {}
    public MyThread(String name) {
        super(name);
    }
    
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName() + "---" + i);
        }
    }
}
  • 给线程起名字有两种办法:
    1、无参构造和有参构造
    2、setName&getName
  • 如何获取main方法所在的线程对象的名称:
    public static Thread currentThread():返回当前正在执行的线程对象
    System.out.println(Thread.currentThread().getName());

2 创建对象

public class MyThreadDemo01 {
    public static void main(String[] args) {
        MyThread my1 = new MyThread();
        MyThread my2 = new MyThread();

        my1.start();
        my2.start();
    }
}

面试题:run()和start()的区别?
run():仅仅是封装被线程执行的代码,直接调用是普通方法
start():首先启动了线程,然后再由jvm去调用该线程的run()方法。

三、线程调度

public final int getPriority():返回线程对象的优先级
public final void setPriority(int newPriority):更改线程的优先级

注意:
线程默认优先级是5
线程优先级的范围是1-10
线程优先级高仅仅表示线程获取的CPU时间片的几率高,但是要在次数比较多,或者多次运行的时候才能看到比较好的效果。

public class MyThreadDemo03 {
    public static void main(String[] args) {
        ThreadPriority tp1 = new ThreadPriority();
        ThreadPriority tp2 = new ThreadPriority();
        ThreadPriority tp3 = new ThreadPriority();
        
        tp1.setName("one");
        tp2.setName("two");
        tp3.setName("three");
        
        tp1.setPriority(10);
        tp2.setPriority(1);
        tp3.setPriority(5);
        
        tp1.start();
        tp2.start();
        tp3.start();
    }
}

四、线程控制

1 休眠线程

public class ThreadSleep extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName() + "---" + i + ",日期:" + new Date());
            // 睡眠

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
  • public static void sleep(long millis)
    在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作收到系统统计时器和调度程序精度和准确性的影响。

2 加入线程

public final void join():等待该线程终止。

public class ThreadJoinDemo01 {
    public static void main(String[] args) {
        ThreadJoin tj1 = new ThreadJoin();
        ThreadJoin tj2 = new ThreadJoin();
        ThreadJoin tj3 = new ThreadJoin();
        
        tj1.setName("1");
        tj2.setName("2");
        tj3.setName("3");
        
        tj1.start();
        try {
            tj1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        tj2.start();
        tj3.start();
    }
}

效果:等待tj1线程结束后,tj2和tj3才能开始抢占CPU资源。

3 礼让线程

public static void yield():暂停当前正在执行的线程对象,并执行其他线程。
在一定程度上让多个线程的执行更和谐,但是不能保证多个线程,一人一次。

public class ThreadYield extends Thread{
    @Override
    public void run() {
        for(int i = 0; i < 100; i++) {
            System.out.println(getName() + "---" + i);
            Thread.yield();
        }
    }
}

效果:理想状态下,线程的执行是你一次我一次,但实际只能在一定程度上有效,并不能完全保证。

4 守护线程

  • public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程、
  • 当正在运行的线程都是守护线程时,Java虚拟机退出。该方法必须在启动线程前调用。
    public static void main(String[] args) {
        ThreadDaemon td1 = new ThreadDaemon();
        ThreadDaemon td2 = new ThreadDaemon();
        
        td1.setName("1");
        td2.setName("2");
        //设置守护线程
        td1.setDaemon(true);
        td2.setDaemon(true);
        
        td1.start();
        td2.start();
        
        Thread.currentThread().setName("000");
        for(int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + "---" + ":" + i);
        }
    }

效果:如果被守护的线程执行完毕,守护线程即刻退出。

5 中断线程

public void interrupt():中断线程。把线程的状态终止,并抛出一个InterruptedException.

public class ThreadStop extends Thread{
    @Override
    public void run() {
        System.out.println("开始执行:" + new Date());
        
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            System.out.println("线程被中断了");
        }
        
        System.out.println("结束执行:" + new Date());
    }
}
    public static void main(String[] args) {
        ThreadStop ts = new ThreadStop();
        ts.start();
        
        try {
            Thread.sleep(3000);
            ts.interrupt(); 
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
    }

相关文章

网友评论

      本文标题:多线程基础(二)

      本文链接:https://www.haomeiwen.com/subject/zocxpqtx.html