Java基础教程之多线程详细分析(2)

      目的:因为自定义的run()方法,所属的对象是Runnable接口的子类对象,所以要让线程去指定对象的run()方法,就必须明确该run()方法的所属对象

  5、调用Thread类的static方法开启线程并调用run()方法

class RunnableTestDemo implements Runnable{
 
    @Override
    public void run() {
        System.out.println("实现Runnable接口");
    }
   
}
public class RunnableTest {
 
    public static void main(String[] args) {
        RunnableTestDemo r = new RunnableTestDemo();
        Thread t1 = new Thread(r);
        t1.start();
    }
}

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

    1、接口方法避免了Java单继承的局限性

    2、继承Thread,线程代码存放在Thread子类run()方法中

    3、实现Runnable接口,线程代码存放在接口紫子类的 run()方法中

  所以,在选择实现Runnable接口与继承Thread这两者中,建议使用实现Runnable接口的方式

线程的状态

Java基础教程之多线程详细分析

    见上图,可看到线程的状态分为:

      1、创建线程(new 线程类),调用start()方法执行run()方法

      2、运行状态:具有执行资格,并且有执行权  

      3、冻结状态:没有执行资格,没有执行权

      4、临时状态(阻塞):具有执行资格,没有执行权。等待cpu的执行权

      5、消亡状态:线程结束

   根据线程的状态的执行原理是:创建一个线程A,调用start()方法,执行run()方法,当线程运行时,遇到sleep(time)或者wait()方法,线程就会进去冻结状态(放弃了执行资格),只有当sleep(time)或者执行了notify()方法,冻结状态就会变成临时状态(阻塞),这时临时状态的线程就会去同其他的线程一起抢夺cpu的执行权,一旦抢到cpu的执行权,该临时状态的线程就会运行(run),变成运行状态run,直到run()方法中的代码执行完,线程才会结束,变成最后的消亡状态。

同步代码块

  较多情况下,Java在处理多线程的时候,会出现一些安全问题,而Java处理多线的安全问题的是方式,是使用同步代码块(synchronized(对象/this/类名.class))或者同步代码函数。

  但是在解决多线程的安全问题时,使用同步代码块的前提是:

    1、必须要有两个或者两个以上的线程

    2、必须是多个线程使用同一个锁(如果存在多个类使用到同步,那么在这几个类中找唯一类,也就是找使用到同步快的共同类)

    3、必须保证听你同步代码块中只能有一个线程在运行。

  同步代码块的好处是解决了线程的安全问题,坏处是多个线程进去同步代码块的时候都要去判断,较为消耗资源。

  在使用同步代码块的前提下,得确认线程是否存在安全性问题,如果找到线程的安全性问题;

    1、明确哪些代码是多线程运行的代码

    2、明确共享数据

    3、明确多线程运行代码中哪些语句是操作的共享数据

同步代码块或者同步代码函数的运行原理:

    1、将需要解决安全问题的代码放到同步代码块中

    2、当多个线程运行时,第一个线程A获得cpu的执行权,首先会来判断真假是否持有锁,如果有,线程A就会进入到同步代码块中,并且进入到里面的第一件时间就是将同步锁给关闭。

    3、然后线程A在同步代码块中,执行同步代码块中的代码。

    4、在此之前,其他线程即使获得cpu的执行权也无法进入到同步代码块中,因为没有获得锁。

    5、当线程A将同步代码块中的代码执行完毕时,最后一步是打开同步锁,然后退出。

    6、这时,其他线程就可以获得cpu的执行权后并且获得同步锁,进入到同步代码块中,执行操作。

public class MyThread implements Runnable{
   
    private static int i = 100; //多个线程共享的数据
    boolean flag = true;
    public  void printVal(){
        if(flag){
            while(true){
                synchronized(this){
                    if(i>0){
                        System.out.println("-----code"+i--);
                    }
                }
            }
        }else{
            while(true){
                printStaticVal();
            }
        }
    }
   
    public static void printStaticVal(){
        while(true){
            synchronized(MyThread.class){
                if(i>0){
                    System.out.println("-----Static"+i--);
                }
            }
        }
    }
   
    public void run(){
        printVal();
        printStaticVal();
    }
 
}
class TestSync {
 
    public static void main(String[] args) {
        TestSync t = new TestSync();
        Thread my1 = new Thread(t);
        Thread my2 = new Thread(t);
        my1.start();
        my2.start();   
    }
}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/950885b733d5a42a63de22038f7abb59.html