java-多线程操作全(Thread)

 一、 多线程概念和作用

 线程指进程中的一个执行场景,也就是执行流程,那么进程和线程的区别是什么

  1.每个进程是一个应用程序,都有独立的内存空间

  2.同一个进程中的线程共享其进程中的内存和资源

  (共享的内存是堆内存和方法内存,栈内存不共享,每个线程有自己的堆内存)

 进程:进程对应一个应用程序

  现在的计算机都是支持多进程的,在同一个操作系统中,可以同时启动多个进程 

  

 多进程的作用:

 * 单进程只能做一件事 : 一边玩游戏,一边听音乐不是同时运行,而是进程之间的频繁调度,切换速度极高,感觉是同时进行。

 * 多线程的作用不是提高执行速度,而是提高CPU的使用率。进程和进程之间的内存是独立的、

 * 线程:是进程中的执行场景。一个进程可以启动多个线程。

 * 多线程的作用:不是为了提高执行速度,而是为了提高应用程序的使用率

 

 * java程序的运行原理

 * java命令启动java虚拟机,启动JVM,等于启动一个应用程序,表明启动一个进程。该进程会自动启动一个“主线程”,然后主线程去调用某各类的main方法。

 * 所以,main方法运行在主线程中。在此之前的所有程序都是单线程的。

 

 二、线程的创建和启动

 

 *Java虚拟机的主线程入口是main方法,用户可以自己创建线程,创建方式有两种

 *1.继承Thread类

 *2.实现Runnable接口(推荐使用Runnable)

 

 *继承Thread类

 *采用 Thread类创建线程,用户只需要继承 Thread,覆盖 Thread中的run方法,父类 Thread中的run方法没有抛出异常,那么子类也不角能抛出异常,最后采用start启动线程即可

 

 实现Runnable接口

 Thread对象本身就实现了 Runnable接口,但一般建议直接使用 Runnable接口来写多线程程序,因为接口会比类带来更多的好处

 

三、java语言中实现多线程第一种方式

 

1.继承java.lang.Thread

2.重写run方法

三个知识点 :定义线程 、创建线程、 启动线程

package com.steven.demo;

import java.lang.Thread;
public class ThreadTest {
  public static void main(String[] args) {

    Thread thread = new Student();
    //启动线程
    thread.start();//打印Run:0~9
    //start方法执行完瞬间结束,告诉JVM再分配一个新的线程 给t线程
    //是随机分配的,没有规律
    
    //run不需要手动调用,系统程序启动之后会自动调用方法
    //thread.run();//这是普通方法的调用,这样做程序只有一个线程,run方法结束之后,下边的程序才会执行
    
    for (int i = 0; i < 5; i++) {
        System.out.println("main"+i);
    }
    //有了多线程之后,main方法结束只是主线程中没有方法栈帧了 但是其他线程或者其他栈中还有栈帧  main方法结束,程序可能还在运行
  }
}

class Student extends Thread {
    //重写Run方法
    public void run() {
       for (int i = 0; i < 10; i++) {
        System.out.println("Run:"+i);
       }
    }
}

四、java语言中实现多线程第二种方式

1.写一个类实现

2.重写run方法

 

package com.steven.demo;

import java.lang.Runnable;
import java.lang.Thread;
public class ThreadTest02 {
   public static void main(String[] args) {
    //创建线程:
    Thread thread = new Thread(new Teacher());
    //启动线程
    thread.start();
   }
}
class Teacher implements Runnable {
    //重写Run方法
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("Run:"+i);
        }
    }
}

五、掌握线程方法

1.获取当前线程的对象 Thread.currentThread()

2.给线程起名t.setName()

3.获取线程的名字:t.getName()

 

package com.steven.demo;
public class ThreadTest03 {
  public static void main(String[] args) {
    
      //获取当前线程的对象 main主线程
      Thread thread = Thread.currentThread();
      //获取当前线程的名字
      System.out.println("当前名称的名称"+thread.getName());//当前名称的名称main
      
      Thread t1 = new Thread(new ArrayTest());
      //给线程起名
      t1.setName("Steven");
      t1.start();//线程的名称Steven
      
      Thread thread2 = new Thread(new ArrayTest());
      //给线程重命名
      thread2.setName("珂珂");
      thread2.start();//线程的名称珂珂
  }
}
class ArrayTest implements Runnable {
    public void run() {
        Thread thread = Thread.currentThread();//获取当前线程的对象
        System.out.println("线程的名称"+thread.getName());
    }
}

六、线程的优先级

优先级高的获取CPU时间片,相对多一些

最高:10

最小:1

默认:5

优先级1-10

优先级高的线程,会得到CPU的时间多一些,优先执行完成

 

public class ThreadTest04 {
  public static void main(String[] args) {
    System.out.println("最高"+Thread.MAX_PRIORITY);
    System.out.println("最小"+Thread.MIN_PRIORITY);
    System.out.println("默认"+Thread.NORM_PRIORITY);
    
    Thread t1 = new Thread(new KeKe());
    t1.setName("t1");
    
    Thread t2 = new Thread(new KeKe());
    t2.setName("t2");
    
    //获取线程的优先级
    System.out.println("t1优先级"+t1.getPriority());
    System.out.println("t2优先级"+t2.getPriority());
    
    //设置优先级
    t1.setPriority(5);
    t2.setPriority(6);
    
    //启动
    t1.start();
    t2.start();//线程虽然有优先级,但是随机分配的,打印结果不一致
  }
}
class KeKe extends Thread {
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+"----------------"+i);
        }
    }
}

七、线程休眠

①Thread.sleep()使当前正在执行的线程执行休眠操作(暂停执行) 单位:毫秒

sleep 静态方法 作用: 阻塞当前线程,腾出CPU,让给其他线程

public class ThreadTest05 {

    public static void main(String[] args) {
        Thread thread = new Array1();
        thread.setName("thread1");
        thread.start();
        //获取当前线程的对象 main主线程
          Thread t = Thread.currentThread();
          //获取当前线程的名字
          System.out.println("当前名称的名称"+t.getName());//当前名称的名称main    
          
          //阻塞主线程
          for (int i = 0; i < 10; i++) {
              System.out.println(Thread.currentThread().getName() + "-------------------:" + i);
                try {
                    Thread.sleep(2000);//程序休眠2秒钟
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
    }
}
class Array1 extends Thread {

    public void run() {
        System.out.println("线程正在启动=-====");
        for (int i = 0 ; i < 5 ; i ++) {
            System.out.println(Thread.currentThread().getName() + "-------------------:" + i);
            try {
                Thread.sleep(2000);//程序休眠2秒钟
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

②Thread.yield()暂停当前正在执行的线程对象,并执行其他线程。

 1.静态方法

 2.作用:给同一个优先级的线程让位,但是让位时间不固定

 3.和sleep方法相同,就是yield的时间不固定

 他与sleep类似,只是不能由用户执行暂停时间,并且yield()只能让同优先级的线程有执行的机会

 

package com.steven.demo;
public class ThreadTest07 {
  public static void main(String[] args) {
      //1.创建线程
       Thread thread = new HThread();
       thread.setName("线程07");
       //2.启动线程
       thread.start();
       //3.主线程
       for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() +"---------:"+i);
        }
       System.out.println("Steven=====");
  }
}
class HThread extends Thread {
    
    public void run() {
        
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() +"---------:"+i);
            if (i % 2 == 0) {
                //暂定当前线程,执行其他线程
                Thread.yield();
            }
        }
    }
}

③线程的基本操作

/*
 线程的基本操作:创建,启动,休眠,异常处理
 */
public class ThreadTest06 {
    
   public static void main(String[] args) {
       try {
         //1.创建线程
           Thread thread = new MyThread();
           thread.setName("线程");
           //2.启动线程
           thread.start();
           //3.休眠
           Thread.sleep(2000);
           System.out.println("Steven=====");
       }catch (InterruptedException e) {
           e.printStackTrace();
       }   
   }
}

class MyThread extends Thread {
    
    public void run() {
        for (int i = 0; i < 10; i++) {
            
            try {
                Thread.sleep(3000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            
            System.out.println(Thread.currentThread().getName() +"---------:"+i);
        }
    }
}

八、线程的合并(join)

public class ThreadTest08 {
   public static void main(String[] args) {
     
   try {
     //1.创建线程
       Thread thread = new KThread();
       thread.setName("线程07");
       //2.启动线程
       thread.start();
       //3.合并线程 (线程07和main线程合并)
       thread.join();//输出只保证一个线程正在执行,依次执行,单线程的程序 (先执行线程07后执行main)
      //主线程
       for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() +"---------:"+i);
        } 
       //当前线程可以调用第一个线程的join方法,调用后当前线程会被阻塞不再执行,直到被调用的线程执行完毕,当前线程才会执行
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
   }
}
class KThread extends Thread {
    
    public void run() {
        
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName() +"---------:"+i);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            };
            
        }
    }
}

九、模拟取款:不使用同步机制,多线程同时对同一个账号进行取款操作

 

public class ThreadTest09 {
   public static void main(String[] args) {
     
   }
}

//取款线程
class Money implements Runnable {

    //账户
    Account account;
    
    public void run() {
        // TODO Auto-generated method stub
        
    }
    
}
class Account {
    private String actno;
    private double balance;
    
    public Account() {}
    public Account(String actno,double balance) {
        this.actno = actno;
        this.balance = balance;
    }
    
    public void setActno(String actno) {
        this.actno = actno;
    }
    
    public String getActno() {
        return actno;
    }
    
    public void setBalance(double balance) {
        this.balance = balance;
    }
    
    public double getBalance() {
        return balance;
    }
}

 

 

猜你喜欢

转载自www.cnblogs.com/StevenHuSir/p/Java_Thread.html