java-多线程-01 详解学习强烈推荐

1.什么是线程

**基本概念**

我们先从线程的基本概念开始,给大家复习一下,不知道有多少同学是基础不太好,说什么是线程都不知道的,如果这样的话,花时间去补初级内容的课。

java-多线程-01 详解学习强烈推荐_第1张图片

什么是叫一个进程? 什么叫一个线程?

- Program app ->QQ.exe

  **进程:**

做一个简单的解释,你的硬盘上有一个简单的程序,这个程序叫QQ.exe,这是一个程序,这个程序是一个静态的概念,它被扔在硬盘上也没人理他,但是当你双击它,弹出一个界面输入账号密码登录进去了,OK,这个时候叫做一个进程。进程相对于程序来说它是一个动态的概念

  **线程:**

作为一个进程里面最小的执行单元它就叫一个线程,用简单的话讲一个程序里不同的执行路径就叫做一个线程

**示例:什么叫做线程**

package com.dazhi.thread;

import java.util.concurrent.TimeUnit;

//什么是线程
public class thread01 {
	/*
	 * 创建线程,可以使用extends Thread和implements Runnable
	 * 
	 * */
	private static class T1 extends Thread{
		@Override
		public void run() {
			for(int i = 0;i<10;i++) {
				try {
					TimeUnit.MICROSECONDS.sleep(1);
				}catch(InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("T1");
			}
		}
		
	}
	
	public static void main(String[] args) {
		/*
		 * start和run区别:
		 * run方法是多线程的线程体
		  *  如果执行start方法,则会在主线程中重新创建一个新的线程,等得到cpu的时间段后则会执行所对应的run方法体的代码。
		  *  故:调用线程的start方法是创建了新的线程,在新的线程中执行。
		  *  调用线程的run方法是在主线程中执行该方法,和调用普通方法一样, 
		 * 
		 * */
		//运行
		//new T1().run();
		
		//启动线程
		new T1().start();
		
		for(int i=0; i<10; i++) {
            try {
                TimeUnit.MICROSECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("main");
        }
	}
}

观察上面程序的数据结果,你会看到字符串“T1”和“Main”的交替输出,这就是程序中有两条不同的执行路径在交叉执行,这就是直观概念上的线程,概念性的东西,理解就好,没有必要咬文嚼字的去背文字的定义。

## 2.线程常用方法

**我们来认识几个线程的方法**

1、sleep:Sleep,意思就是睡眠,当前线程暂停一段时间让给别的线程去运行。
      Sleep是怎么复活的?由你的睡眠时间而定,等睡眠到规定的时间自动复活

package com.dazhi.thread;

public class thread02 {
	 public static void main(String[] args) {
	    testSleep();
	    //testYield();
	    //testJoin();
	 } 
	 
	 /*
	  * Sleep,意思就是睡眠,当前线程暂停一段时间让给别的线程去运行。
	  * Sleep是怎么复活的?由你的睡眠时间而定,等睡眠到规定的时间自动复活
	 */
    static void testSleep() {
        new Thread(()->{
            for(int i=0; i<100; i++) {
                System.out.println("A" + i);
                try {
                    Thread.sleep(500);
                    //TimeUnit.Milliseconds.sleep(500)
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

2、Yield:就是当前线程正在执行的时候停止下来进入等待队列,回到等待队列里在系统的调度算法里头呢还是依然有可能把你刚回去的这个线程拿回来继续执行,当然,更大的可能性是把原来等待的那些拿出一个来执行,所以yield的意思是我让出一下CPU,后面你们能不能抢到那我不管

package com.dazhi.thread;

public class thread02 {
	  public static void main(String[] args) {
		//testSleep();
		testYield();
		 //testJoin();
	 } 
	 
	
    /*
     * Yield,就是当前线程正在执行的时候停止下来进入等待队列,
	      * 回到等待队列里,在系统的调度算法里头呢,还是依然有可能把你刚
	      * 回去的这个线程拿回来继续执行,当然,更大的可能性是把原来等待
	      * 的那些拿出一个来执行,所以yield的意思是我让出一下CPU,
	      * 后面你们能不能抢到那我不管
      */
    static void testYield() {
        new Thread(()->{
            for(int i=0; i<100; i++) {
                System.out.println("A" + i);
                if(i%10 == 0) Thread.yield();
            }
        }).start();

        new Thread(()->{
            for(int i=0; i<100; i++) {
                System.out.println("------------B" + i);
                if(i%10 == 0) Thread.yield();
            }
        }).start();
    }
}

3、join:join, 意思就是在自己当前线程加入你调用Join的线程(),本线程等待。等调用的线程运行完了,自己再去执行。t1和t2两个 线程,在t1的某个点上调用了t2.join,它会跑到t2去运行,t1等待t2运行完毕继续t1运行(自己join自己没有意义)

package com.dazhi.thread;

public class thread02 {
	 public static void main(String[] args) {
		//testSleep();
		//testYield();
		 testJoin();
	 } 
    
    /*
     * join, 意思就是在自己当前线程加入你调用Join的线程(),
	* 本线程等待。等调用的线程运行完了,自己再去执行。t1和t2两个
	* 线程,在t1的某个点上调用了t2.join,它会跑到t2去运行,t1
	* 等待t2运行完毕继续t1运行(自己join自己没有意义)
	*/
    static void testJoin() {
        Thread t1 = new Thread(()->{
            for(int i=0; i<100; i++) {
                System.out.println("A" + i);
                try {
                    Thread.sleep(100);
                    //TimeUnit.Milliseconds.sleep(500)
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread t2 = new Thread(()->{

            try {
                t1.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            for(int i=0; i<100; i++) {
                System.out.println("B" + i);
                try {
                    Thread.sleep(100);
                    //TimeUnit.Milliseconds.sleep(500)
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        t1.start();
        t2.start();
    }
}

## 3.启动线程的五种方式

**创建线程的几种方式**

package com.dazhi.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

public class thread03 {
	static class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println("Hello MyThread!");
        }
    }
	static class MyRun implements Runnable {
        @Override
        public void run() {
            System.out.println("Hello MyRun!");
        }
    }
	static class MyCall implements Callable {
        @Override
        public String call() {
            System.out.println("Hello MyCall");
            return "success";
        }
    }
	//启动线程的5种方式
	public static void main(String[] args) {
		//1
		new MyThread().start();
		//2
		new Thread(new MyRun()).start();
		//3
		new Thread(()->{
            System.out.println("Hello Lambda!");
        }).start();
		//4
		Thread t = new Thread(new FutureTask(new MyCall()));
        t.start();
        //5
        ExecutorService service = Executors.newCachedThreadPool();
        service.execute(()->{
            System.out.println("Hello ThreadPool");
        });
        service.shutdown();
	}
}

**分享一道面试题**

请你告诉我启动线程的三种方式 ?
你说第一个:new Thread().start(); 第二个: new Thread(Runnable).start() 这没问题 ;那第三个呢,要回答线程池也是用的这两种之一,他这么问有些吹毛求疵的意思,你就可以说通过线程池也可以启动一个新的线程 3:Executors.newCachedThreadPool()或者FutureTask + Callable

你可能感兴趣的:(JAVA)