多线程

Java多线程

关键技能与概念

1.理解多线程的基础知识

多任务有两种不同的类型:

(1)基于进程的多任务

(2)基于线程的多任务

这两个有什么区别呢?

进程的本质上是指正在执行的程序,所以进程的多任务是指计算机同时运行两个或多个程序功能。打开任务管理器,你会发现有很多程序在运行
在这里插入图片描述

你会发现有很多任务在同时运行。这属于基于进程的多任务。

而基于线程的多任务环境中,线程是最小的可调度代码单元。

这意味着,程序一次可以执行多项任务,需要多核CPU处理。

对于线程呢?

也就是程序运行的路线,它将如何执行程序,当前程序执行完后下一个运行执行啥程序?线程有两种装态,一是运行状态(running),二是就绪状态,一旦得到CPU的时间就开始执行。

并行与并发

其实这两个慨念很简单,并行则是多个线程在同一时间运行,而并发是多个线程轮流执行,比如循环排队。

Thread类和Runnable接口

首先我们来探索 Thread类的几个常用方法。

方法含义
final String getName()获取线程名
final int getPriority()获取线程优先级
final boolean isAlive()判断该线程是否在运行
final void join()等待线程终止
void run()线程的进入点
static void sleep(long milliseconds)按照指定的时间挂起线程以毫秒为单位
void start()通过调用线程的run方法启动线程

1.实现Runnable接口实现的多线程

package threadTest;
// 通过实例化一个Thread类型对象可以创建一个线程。
// Thread类封装可运行对象
// 主要步骤为 1. 实现 Runnable 接口  2. 扩展 Tread 类。
/*
在 Runnable 接口抽象了一个可执行代码单元,可以在实现Runnable接口的任何对象上构造线程。
但实际上
Runnable 类中只有一个方法 :
 public void run();
 是不很好奇 为什么只有一个方法,其实这只是写多线程的一个规范。
 在创建一个实现Runnable接口后再实例化一个Thread 类型的对象,在Thread类中有好几个构造方法如下:
                     Thread (Runnable ThreadObject)
 再调用 start() 方法运行线程
 */
// 我想。有没有小伙伴根据以上文字的描叙,自己写一段代码
// 可以的话 ,欢迎在评论区留言。
public class MyThread implements Runnable{
    String ThreadName;
    public MyThread (String ThreadName){
        this.ThreadName = ThreadName;
    }
    public void run(){
        System.out.println(ThreadName +"staring");
        try {
            for (int count = 0; count < 10; count++) {
                Thread.sleep(100);
                System.out.println("In" + ThreadName + ", count is " + count);
            }
        }
            catch (InterruptedException exc){
                 System.out.println(ThreadName+"interrupted.");
            }
        System.out.println(ThreadName +" terminating.");
        }
    }
    class UseThreads {
    public static void main(String [] args){
        System.out.println("Main threading staring ");
        // First ,construct a MyThread object .
        MyThread mt = new MyThread("You love me"); // 创建一个运行对象
        Thread newThread = new Thread(mt); // 在该对象上构造一个线程。
        newThread.start();
        for(int i=0;i<10;i++) {
            System.out.println("I love you" + " " + i);
            try {
                Thread.sleep(200);
            } catch (InterruptedException exc) {
                    System.out.println("Main thread interrupted");
            }
        }
        System.out.println(" Main thread ending");
q
    }
    }
    /* /输出结果如下:
 Main threading staring 
You love me staring
I love you 0
InYou love me , count is 0
InYou love me , count is 1
I love you 1
InYou love me , count is 2
I love you 2
InYou love me , count is 3
InYou love me , count is 4
I love you 3
InYou love me , count is 5
InYou love me , count is 6
I love you 4
InYou love me , count is 7
InYou love me , count is 8
I love you 5
InYou love me , count is 9
You love me  terminating.
I love you 6
I love you 7
I love you 8
I love you 9
 Main thread ending

Process finished with exit code 0

     */
     // 可以看的出来 Love you 与 Love me 并不是一次性输出而是间断性的输出。
// 这就是我在前面说的并发

以上代码还可以改写为如下代码,希望小伙伴能找到不同之处,并分析为什要这样写,有什么好处。

class MyThread implements Runnable{
    Thread thread ; // 线程的引用
    // Construct a  new thread using this Runnable and give
    MyThread(String name){
        thread = new Thread(this,name);
    }
    public static MyThread createAndStart(String name){
        MyThread myThread = new MyThread(name);
        myThread.thread.start(); // 开始执行线程
        return myThread;
    }
    public void run(){
        System.out.println(thread.getName()+"staring");
        try{
            for(int count =0;count<10;count++){
                Thread.sleep(400);
                System.out.println("I Love you "+thread.getName() + "count is :" +count);
            }
        }
        catch(InterruptedException exc){
            System.out.println("Thread is interrupted"+thread.getName());
        }
        System.out.println(thread.getName()+" terminating.");
    }

}
class ThreadVariations{
    public static void main(String [] args){
        System.out.println("Main thread starting");
        // Create and start a thread;
        MyThread f = MyThread.createAndStart("You love me");
        for(int i =0;i<50;i++){
            System.out.println(f.thread.getName());
            try{
                Thread.sleep(100);
            }
            catch(InterruptedException exc){
                System.out.println("Main thread interrupted");
            }
        }
        System.out.println("Main Thread ending");
    }
}

2.继承Thread类的线程

注意,继承Thread类重写的是Thread 类中的Run反法,相当于简接的实现Runnable中的run犯法,而1.中则是直接实现run方法。

一个是重写。一个是实现接口。两者那种方法更好

欢迎在评论区留言!

public class ExtendThread {
    public static void main(String [] args){
        System.out.println("Main thread starting");
        MyThread01 fy = new MyThread01("You Love me ");
        fy.start();
        for(int i =0;i<50;i++){
            System.out.println(fy.getName());
            try{
                Thread.sleep(500);
            }
            catch(InterruptedException exc){
                System.out.println("Main Thread ");
            }
        }
        System.out.println("Thread is ending");
    }
}
class MyThread01 extends Thread{
    MyThread01(String name){
        super(name); // name thread.
    }   // 用super调用父类的构造方法Thread(String threadName)
    // 添加 run() 方法
    public void run() {
        System.out.println(getName() + "Thread staring");
        try{
            for (int count = 0; count < 10; count++) {
                Thread.sleep(100);
                System.out.println(getName() + "I Love you" + " count is" + count);
            }
        }
        catch(InterruptedException exc){
            System.out.println(getName() + "interrupted.");
        }
        System.out.println(getName()+"线程结束");
    }
}

1.3创建多个线程

实际上创建多个线程,无非就是多new几个对象,当然也可以多写几个不同的线程,用于完成不同的功能。但是重run方法的基本格式是固定的必须要有try catch 语句。


import java.util.Scanner;
public class ManyThread implements Runnable {
    Thread thread ;
    // Construct a new thread .
    ManyThread (String name){
        thread = new Thread(this,name);
    }
    // a factory method that creates and starts a thread
    public static ManyThread createAndStart (String name ){
        ManyThread manythread = new ManyThread("I Love you");
        manythread.thread.start(); // start the thread
        return manythread;
    }
    public void run(){
        System.out.println(thread.getName() + " Starting .");
        try {
                   for(int i =0 ; i<10;i++){
                       Thread.sleep(400);
                       System.out.println(" " + thread.getName()+",count is "+ i);
                   }
        }catch(InterruptedException exc ){
            System.out.println(thread.getName()+"Interruption");
        }
    }
}
class MoreThread{
    public static void main(String [] args){
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        System.out.println("Main Thread staring ");
        ManyThread m1 = ManyThread.createAndStart("我爱你");
        ManyThread m2 = ManyThread.createAndStart("你爱我");
        ManyThread m3 = ManyThread.createAndStart("如果我们两个互不相爱");
        for(int i =0 ;i<n;i++){
            System.out.print(".");
            try{
                Thread.sleep(100);
                 if(m1.thread.isAlive())
                    System.out.println("线程没有结束");
            }
            catch(InterruptedException exc){
                System.out.println("Main Thread Interruption");
            }
        }
        System.out.println("Main Thread ending");
    }
}

1.4确认线程如何结束

其实这个很简单,可以使用 Thread提供的方法

final boolean isAlive()
//使用举例
    //  if(m1.thread.isAlive())
    //             System.out.println("线程没有结束");
    // 如果线程没有结束,该方法反回 ture 如果结束反回 false。
    但在API 文档中的方法为
  // public final native boolean isAlive();
      /**
     * Tests if this thread is alive. A thread is alive if it has
     * been started and has not yet died.
     *
     * @return  {@code true} if this thread is alive;
     *          {@code false} otherwise.
     */
    /*
    此时的我,产生了疑问,单凭这简单的一句是则么做到的?
    我发现在方法前有一个
    @Contract(pure = ture)
    这是什莫意思呢。
    */

1.5线程的优先级

总体来说就是CPU给一条线程分配的时间有多少,优先级高的分配的时间就多,而优先级低的分配时间就少。注意:

除了优先级外,,还有其它因素对分配多少时间给线程的CPU时间

如 : 一个高优先级的线程正在等待某一资源的输入(可能是键盘的输入),这样它就会被堵塞,而运行优先·级较低的线程。

这说明了,优先级高的线程不一定先执行,当然还有其它因素。

如何设置线程的优先级?

调用Thread类中的setPriority()方法来修改线程的优先级:

final void setPriority(int level)

其中这个 level 的值必须在MIN_PRIORITY和MAX_PRIORITY的范围内,值一般为1~10。如何看线程默认的优先级呢?这就要用到

getPriority方法。

final int getPriority()

这些方法都有一些特性都是用final关键字修饰,说明sun公司的那帮人不想让人更改它们已经写好的方法,你只管用就行。

列题


public class Priority implements Runnable {
          int count ;
          Thread thread ;
          static boolean stop = false;
          static String currentName; // 现在流通的名字
          // Construct a new Thread
          Priority (String name){
              thread = new Thread(name);
              count = 0;
              currentName = name;
          }
          // Entry point of thread .
    public void run(){
              System.out.println(thread.getName()+"staring");
              do {
                  count++;

                  if(currentName.compareTo(thread.getName())!=0){
                          currentName = thread.getName();
                          System.out.println(" In "+currentName);
                  }
              }while(stop ==false&&count <1000000 );
              stop = true;
              System.out.println("/n"+thread.getName()+"terminating");
    }
}
class PriorityDemo{
    public static void main(String [] args){
           Priority m1  = new Priority("High Priority");
           Priority m2 = new Priority("Low Priority");
           Priority m3 = new Priority("normal Priority #1");
           Priority m4 = new Priority("normal Priority #2");
           Priority m5 = new Priority ("normal Priority #3");
           // set the priority
        // 线程的基本流程就是new 完对象就开起线程。
        // start the thread
        m1.thread.start();
        m2.thread.start();
        m3.thread.start();
        m4.thread.start();
        m5.thread.start();
        try{
            m1.thread.join();
            m2.thread.join();
            m3.thread.join();
            m4.thread.join();
            m5.thread.join();
        }catch(InterruptedException exc){
            System.out.println("Main thread interrupted");
        }
        System.out.println("\nHigh priority thread counted to"+m1.count);
        System.out.println("\nLow priority thread counted to"+m2.count);
        System.out.println("\nNormal priority thread counted to"+m3.count);
        System.out.println("\nNormal priority thread counted to"+m4.count);
        System.out.println("\nNormal priority thread counted to"+m5.count);

    }
}
/*
  public int compareTo(String anotherString) {
        byte v1[] = value;
        byte v2[] = anotherString.value;
        byte coder = coder();
        if (coder == anotherString.coder()) {
            return coder == LATIN1 ? StringLatin1.compareTo(v1, v2)
                                   : StringUTF16.compareTo(v1, v2);
        }
        return coder == LATIN1 ? StringLatin1.compareToUTF16(v1, v2)
                               : StringUTF16.compareToLatin1(v1, v2);
     }
 */

 v2[] = anotherString.value;
        byte coder = coder();
        if (coder == anotherString.coder()) {
            return coder == LATIN1 ? StringLatin1.compareTo(v1, v2)
                                   : StringUTF16.compareTo(v1, v2);
        }
        return coder == LATIN1 ? StringLatin1.compareToUTF16(v1, v2)
                               : StringUTF16.compareToLatin1(v1, v2);
     }
 */

以上线程的基础操作。在接下来的几天我会跟新同步,线程的通信。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

“逢雨”

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值