ava多线程和C++里面的多线程有些地方不一样。

毕竟套了一个java虚拟机。对此记录下。

 

 

 

Java语言内置多线程支持:

一个java程序实际上是一个JVM进程。

JVM用一个主线程来执行main()方法。

在main()方法中又可以启动多个进程。

 

 

Java多线程创建MyThread类逻辑:

1. 从Thread派生;

2. 覆写run()方法;

3. 创建MyThread实例;

4. 调用start()启动线程。

创建一个线程对象,并启动一个线程。

Thread t = new Thread();
t.start();

如果一个类已经从某个类派生,无法从Thread继承,那么需要的逻辑:

1. 实现Runable接口;

2. 覆写run()方法;

3. 在main()方法中创建Runnable实例;

4. 创建Thread实例并传入Runnable;

5. 调用start()启动线程。

 

 

如下代码:

class Thread1 extends Thread{

    String name;
    public Thread1(String name){

        this.name = name;
    }

    @Override
    public void run() {

        for(int i = 0; i < 5; i++){

            System.out.println("[" + Thread.currentThread().getId() + "]" + " " + name);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


public class Main1 {

    public static void main(String[] args){

        Thread1 t1 = new Thread1("线程1");
        t1.start();
        Thread1 t2 = new Thread1("线程2");
        t2.start();
        System.out.println("Over!");

    }
}

程序运行截图如下:

这里要注意:为什么主线程已经结束了,子线程还在跑。

Java没有严格的主线程和子线程的概念。除非主线程终止了子线程,否则子线程会一直执行。

 

下面是线程的优先级:

可以对线程设置优先级Thread.setPriority(int n)// 1~10,默认为5

优先级高的线程被操作系统调度优先级高

不能通过设置优先级来确保先后顺序。

 

 

Java多线程的状态:

New(新创建)、Runnable(运行中)、Blocked(被阻塞)、Waiting(等待)、Timed Waiting(计时等待)、Terminated(已种子)

 

线程终止的原因:

run()方法执行到return语句返回(线程正常结束)

因为未捕获的移除导致线程终止(线程意外终止)

对某个线程的Thread实例调用stop()方法强制终止(不推荐)

 

如下代码:

class MyThread extends Thread{

    String name;

    public MyThread(String name){

        this.name = name;
    }

    @Override
    public void run() {

        for(int i = 0; i < 5; i++){

            System.out.println("[" + Thread.currentThread().getId() + "]" + " " + name);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class Main2 {

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

        MyThread myThread = new MyThread("线程");
        System.out.println("线程");
        myThread.start();
        myThread.join();    //等待myThread执行结束
        System.out.println("END");
    }
}

程序运行截图如下:

如果线程需要执行一个长时间任务,就可能需要能中断线程。

中断线程就是其他线程给该线程发一个信号,该线程收到信号后结束执行run()方法。

中断线程需要通过检测inlnterrupted()标志。

其他线程通过调用interrupt()方法中断该线程。

代码如下:

class MyThread2 extends Thread{

    @Override
    public void run() {

        while(!isInterrupted()){

            System.out.println("[" + Thread.currentThread().getId() + "]" + " " + "Hello");
        }
    }
}

public class Main3 {

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

        MyThread2 myThread = new MyThread2();
        myThread.start();
        Thread.sleep(1000);
        myThread.interrupt();
    }
}

程序运行截图如下:

如果线程处于等待状态,该线程会捕获InterruptedException

捕获到InterruptedException说明有其他线程对其调用了interrupt()方法。通常情况下该线程会立刻结束运行

代码如下:

class MyThread3 extends Thread{

    @Override
    public void run() {

        while(!isInterrupted()){

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

public class Main4 {

    public static void main(String[] args){

    }
}

还可以设置running标志位,这个就和C++里面常用的方法一样。外部通过修改一个成员的状态来让其退出。

但是不同的是,java有个java虚拟机。这个和C++里面的不一样。

要用volatile关键字,如下:public volatile boolean running = false;

 

 

Java虚拟机里面,有给主内存的概念,其实任意变量都是在主内存中,当创建了线程后,会在线程中有给变量,这个变量同时也会在主内存中,有一个变量与之对于。

如下:

 

这样在跟新的时候,就会存中误差。所以就需要volatile关键字:

volatile关键字的目的是告诉虚拟机:

每次访问变量时,总是获取主内存的最新值。

每次修改变量后,立刻回写到主内存。

 

Volatile关键字解决的是可见性问题:

当一个线程修改了某个共享变量的值,其他线程能够立刻看到修改后的值。

代码如下:

class MyThread5 extends Thread{

    public volatile boolean running = true;

    @Override
    public void run() {


        while(running){

            System.out.println("Hello");

            try {

                Thread.sleep(100);
            }
            catch (InterruptedException e) {

                e.printStackTrace();
                System.out.println("InterruptedException");
                break;
            }
        }
    }
}

public class Main5 {

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

        MyThread5 myThread5 = new MyThread5();
        myThread5.start();
        Thread.sleep(1000);
        myThread5.running = false;
        System.out.println("end");
    }
}

程序运行截图如下:

源码打包下载地址:https://github.com/fengfanchen/Java/tree/master/MultiThreadInJav

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐