Java基础_17 | Java多线程程序设计(Java中两种创建线程的方法、多线程之间的同步和互斥)

1. 多线程实现最核心的机制

一个程序在其执行过程中, 可以产生多个线程, 形成多条执行线索。,每条线程,有产生、存在和消亡的过程,并且独立完成各自的功能,互不干扰。

多线程程序运行只占用一个CPU,使用“时间片轮转法”运行程序,如图:

2. Java中的多线程实现

Java应用程序总是从主类的main()方法开始执行,如果main()方法中创建了其它线程,在主线程和其它线程之间轮流切换执行,保证每个线程都有机会使用CPU,直到程序中所有线程都结束, Java应用程序才结束。

在Java中,每个线程的状态有以下四种:

线程状态切换时调用的方法在图中已标示出来,这些对线程进行操作的方法都在java.lang.Thread 类中,这个类是专门用来创建线程和对线程进行操作的类,还包括特殊的 run( )方法。

在Java中,创建线程有两种方法:

  • 继承Thread类
  • 实现Runnable接口

线程创建方法1—继承Thread类

具体定义方法如下:

  • ① 定义类的时候继承Thread类;
  • ② 重写 Thread 类的 run() 方法;
  • ③ 准备在线程中完成的工作放在run() 方法实现;

定义之后创建对象,然后通过该对象调用start()方法即可启动线程。

示例代码如下:

import java.lang.Thread;

class MyThread extends Thread {
    String name;
    int count;
    MyThread(String name, int count){
        this.name = name;
        this.count = count;
    }

    public void run() {
        for(int i = 0; i < count;i++) {
            System.out.println(name + ":" + i);
        }
    }
}

public class ThreadTest {
    public static void main(String[] args) {
        //创建线程
        MyThread myThread1 = new MyThread("A",5);
        MyThread myThread2 = new MyThread("B",5);

        //启动线程
        myThread1.run();
        myThread2.run();
    }
}

运行效果如下:

线程创建方法2—实现Runnable接口

具体定义方法如下:

  • ① 定义类的时候实现Runnable接口;
  • ② 重写接口中的 run() 方法;
  • ③ 准备在线程中完成的工作放在run() 方法实现;

定义之后创建对象,然后通过该对象调用start()方法即可启动线程。

示例代码如下:

import java.lang.Thread;

class MyTestThread implements Runnable{
    String name;
    int count;
    MyTestThread(String name, int count){
        this.name = name;
        this.count = count;
    }

    public void run() {
        for(int i = 0; i < count;i++) {
            System.out.println(name + ":" + i);
        }
    }
}

public class ThreadTest2 {
    public static void main(String[] args) {
        //创建线程
        MyTestThread myThread1 = new MyTestThread("A",3);
        MyTestThread myThread2 = new MyTestThread("B",3);

        //启动线程
        myThread1.run();
        myThread2.run();
    }
}

运行效果如下:

3. 多线程之间的同步和互斥

在多线程程序中,可能会有两个甚至更多的线程试图同时访问一个有限的资源,在编写程序时必须对这种潜在资源冲突进行预防。

为了解决这种冲突,在线程使用一个资源时为其加锁即可,访问资源的第一个线程为其加上锁以后,其他线程便不能再使用那个资源,除非被解锁

加锁的方法非常简单,只需要对于访问某个关键共享资源的所有方法,加上synchronized修饰符即可,比如:

synchronized void f();

加锁之后,其它线程想使用这个方法时就必须等待,直到线程A 使用完该方法,除非线程A主动让出CPU资源。

示例代码如下:

import java.lang.Thread;

class MySyncThread implements Runnable{
    String name;
    int count;
    /* 所有该类对象共享资源 */
    private static int number = 100;

    MySyncThread(String name, int count){
        this.name = name;
        this.count = count;
    }

    public void run() {
        int temp;
        for(int i = 0; i < count;i++) {
            temp = sub();
            System.out.println(name + ":number = " + number);
            //主动挂起,让出CPU
            try {
                Thread.sleep(2000);
            }
            catch (Exception e) {
                System.out.println("发生异常啦!");
            }
        }
    }

    /* 上锁 */
    public  synchronized int sub() {
        number--;
        return number;
    }
}

public class ThreadTest3 {
    public static void main(String[] args) {
        //创建线程
        MySyncThread myThread1 = new MySyncThread("A",3);
        MySyncThread myThread2 = new MySyncThread("B",3);

        //启动线程
        myThread1.run();
        myThread2.run();
    }
}

运行效果如下:

发布了216 篇原创文章 · 获赞 575 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/Mculover666/article/details/104369313
今日推荐