【我的Java笔记】多线程_多线程的概述 & 实现方式

进程

1.进程的概念:

正在运行的程序。进程是系统分配资源调用的一个独立单位


2.多进程的意义:

(1)计算机在做一件事情的同时还可以做另一件事

(2)为了提高CPU的使用率


3.多进程:两个程序之间并不是同时进行,而是由CPU的一点点时间片在两者之间的高效切换





线程


1.线程是依赖于进程存在,一个线程相当于进程中的某个任务


2.线程的概念:

(1)多线程:一个程序的执行路径有多条

(2)单线程:一个程序的执行路径只有一条


3.多线程的意义:

一个进程中开启了多个任务,每一个任务(线程)在互相抢占CPU的执行权(可以提高执行效率

4.多线程的特点:线程的执行具有随机性


注:Java虚拟机JVM是多线程程序吗?

是多线程程序,Java虚拟机自带垃圾回收器,来确保程序不会轻易造成内存溢出

(1)主线程:当前程序在执行代码时,开启main方法

(2)子线程:垃圾回收器


5.进程和线程的关系:线程的实现需依赖于一个进程的创建


6.并发和并行的概念:

(1)并发:指的是同一个时间点

(2)并行:指的是一个时间段


7.线程的生命周期图解:

【我的Java笔记】多线程_多线程的概述 & 实现方式_第1张图片




多线程的实现方式

*方式1:
(1)自定义一个类,继承自Thread类
(2)自定义类重写Thread类中的 run() 方法
(3)在主线程(main)中,创建该类的实例对象,启动线程





*方式2:
 通过构造方式:public Thread (Runnable target , String name)
(1)自定义一个类,该类实现 Runnable 接口
(2)实现接口中的 run() 方法
(3)在主线程中创建该类的实例对象
(4)创建Thread对象,将步骤(3)的对象做为参数传递
(5)分别启动线程 





*方式3:
多线程实现的第三种方式:线程池
(详见博客《多线程的第三种实现方式(线程池)》)





问题:为什么有了第一种创建线程的的方式,还要第二种接口的方式?
答:第一种方式使用了继承的方式,而单继承具有局限性。
而第二种方式更符合Java的设计原则以及设计模式:数据分离原则
MyRunnable对象作为两个子线程的共有对象(共享数据),Java中多线程实现方式接口多一些






Thread类(实现Runnable接口)

1.Thread类中的构造方式:

(1)public Thread () 分配新的Thread对象

(2)public Thread (Runnable target , String name)参数一为Runnable接口对象


注:run() 方法内执行的都为耗时操作(耗时操作:线程等待、线程睡眠、循环语句)


2.Thread成员方法:

(1)public void start()使该线程开始执行,Java 虚拟机调用该线程的 run 方法

注:线程若启动结束后不能再启动,第二次启动会出现非法线程状态异常

(2)public void run()Thread的子类重写此方法,由Java虚拟机调用

注:run() 不能启动线程,run() 为一个普通的方法,并不会出现线程的随机性,而start() 方法调用其实是通过JVM调用线程中的run() 来进行多个线程抢占CPU的执行权(线程之间互相抢占)

(3)public static Thread currentThread()返回对当前正在执行的线程对象的引用

①线程的命名和获取方法:

(1)public final void setName(String name)改变线程名称,使之与参数 name 相同

(2)public final String getName()返回该线程的名称

②线程的优先级:

(1)public final int getPriority()返回线程的优先级

(2)public final void setPriority(int newPriority)更改线程的优先级

注:线程的优先级默认=5,最大优先级=10,最小优先级=1

(线程的执行具有随机性,虽然确定了优先级,但优先级只是概率事件,优先级大则抢到执行权的概率大)

③线程的停止:

(7)public final void stop()强迫线程停止执行

注:此方法线程会强行停止,不会再执行下面的操作
(8)public void interrupt()中断线程

注:中断标记,只是一种状态,下面的线程还会执行

④join和yieid方法:

(1)public static void yield()暂停当前正在执行的线程对象,并执行其他线程

注:几个线程之间换着执行,如线程1,线程2,线程1,线程2······(该方法不受优先级影响)
(2)public final void join()等待该线程终止

注:放置于线程执行之后,如:线程1.start();线程1.join();线程2.start;则线程1先执行完结束之后才会执行线程2


⑤线程的睡眠:

(1)public static void sleep(long millis)在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)


⑥守护线程:

(1)public final void setDaemon(boolean on)当参数为true时,设置为守护线程

注:该方法必须在 start() 开始之前调用,当主线程完成后,守护线程过段时间也会自己消亡(并不会在主线程结束之后立即消亡)

撒打算






一、多线程的第一种实现方式


例1:线程命名的两种方式

public class ThreadDemo {

	public static void main(String[] args) {

		// 线程命名方式1:通过自定义类的有参构造
		MyThread my1 = new MyThread("线程1");
		MyThread my2 = new MyThread("线程2");
		my1.start();
		my2.start();

		// 线程命名方式2:通过无参构造+setName(String name)方法
		MyThread my3 = new MyThread();
		MyThread my4 = new MyThread();
		my3.setName("线程3");
		my4.setName("线程4");

		my3.start();
		my4.start();

	}
}

class MyThread extends Thread {

	public MyThread() {

	}

	public MyThread(String name) {
		super(name);
	}

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println(getName() + ":" + i);
		}
	}

}





例2:更改线程的优先级 setPriority(int newPriority)

public class ProrityDemo {

	public static void main(String[] args) {

		// 创建该线程的实例
		MyPriority mp1 = new MyPriority();
		MyPriority mp2 = new MyPriority();
		MyPriority mp3 = new MyPriority();

		// 设置线程名称:无参构造+setName()方法
		mp1.setName("伊卡尔迪");
		mp2.setName("佩里西奇");
		mp3.setName("汉达诺维奇");

		// 给线程设置优先级
		mp1.setPriority(10);
		mp2.setPriority(1);
		mp3.setPriority(7);

		// 启动线程
		mp1.start();
		mp2.start();
		mp3.start();
	}
}

// 自定义的线程类
class MyPriority extends Thread {

	@Override
	public void run() {
		for (int x = 0; x < 5; x++) {
			System.out.println(getName() + ":" + x);
		}
	}
}


【我的Java笔记】多线程_多线程的概述 & 实现方式_第2张图片

注:此种方法虽然设置了优先级,但优先级只是概率事件,线程的执行基友随机性







例3:join() 等待线程终止

public class JoinDemo {

	public static void main(String[] args) {

		// 创建该线程的实例对象
		JoinThread jt1 = new JoinThread();
		JoinThread jt2 = new JoinThread();
		JoinThread jt3 = new JoinThread();

		// 设置线程名称
		jt1.setName("伊卡尔迪1");
		jt2.setName("佩里西奇2");
		jt3.setName("坎德雷瓦3");

		// 启动线程
		jt1.start();

		// 设置线程等待该线程终止该方法必须要启动线程
		try {
			jt1.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		//等待线程jt1终止才会执行线程jt2和jt3
		jt2.start();
		jt3.start();
	}
}

// 自定义的线程类
class JoinThread extends Thread {

	@Override
	public void run() {
	
		for (int x = 0; x < 5; x++) {
			System.out.println(Thread.currentThread().getName() + ":" + x);
			
		}
	}
}

【我的Java笔记】多线程_多线程的概述 & 实现方式_第3张图片







例4:yield() 暂停当前正在执行的线程对象,并执行其他线程

public class YieldDemo {

	public static void main(String[] args) {

		// 创建线程类对象
		YieldThread yt1 = new YieldThread();
		YieldThread yt2 = new YieldThread();
		YieldThread yt3 = new YieldThread();

		// 设置线程名称
		yt1.setName("线程1");
		yt2.setName("线程2");
		yt3.setName("线程3");
		
		//设置优先级
		yt1.setPriority(9);
		yt2.setPriority(5);
		yt3.setPriority(1);

		// 启动线程
		yt1.start();
		yt2.start();
		yt3.start();
	}
}

// 自定义线程类
class YieldThread extends Thread {

	@Override
	public void run() {
		
		for (int x = 0; x < 5; x++) {
			System.out.println(getName() + ":" + x);
			// 加入yield()方法
			Thread.yield();
		}
	}
}


【我的Java笔记】多线程_多线程的概述 & 实现方式_第4张图片

注:该方法不受优先级影响







例5:setDaemon(true)将一个线程设置为守护线程

public class DaemonDemo {

	public static void main(String[] args) {

		// 创建线程类对象
		ThreadDeamon td1 = new ThreadDeamon();
		ThreadDeamon td2 = new ThreadDeamon();

		// 设置线程名称
		td1.setName("什克里尼亚尔");
		td2.setName("米兰达");

		// 设置为守护线程	setDaemon(true)
		td1.setDaemon(true);
		td2.setDaemon(true);

		// 启动线程
		td1.start();
		td2.start();
		
		// 设置主线程
		Thread.currentThread().setName("国际米兰");
		for (int x = 0; x < 3; x++) {
			System.out.println(Thread.currentThread().getName() + ":" + x); 
		}
	}
}

// 自定义线程类
class ThreadDeamon extends Thread {

	@Override
	public void run() {
		for (int x = 0; x < 20; x++) {
			System.out.println(getName() + ":" + x);
		}
	}
}


【我的Java笔记】多线程_多线程的概述 & 实现方式_第5张图片

注:待主线程结束之后,守护线程过会儿才会消亡







例6:sleep(long millis)在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)

import java.util.Date;

public class SleepDemo {

	public static void main(String[] args) {

		// 创建线程类对象
		ThreadSleep ts1 = new ThreadSleep();
		ThreadSleep ts2 = new ThreadSleep();
		ThreadSleep ts3 = new ThreadSleep();

		// 设置线程名称
		ts1.setName("线程1");
		ts2.setName("线程2");
		ts3.setName("线程3");

		// 启动线程
		ts1.start();
		ts2.start();
		ts3.start();
	}
}

class ThreadSleep extends Thread {

	@Override
	public void run() {
		
		for (int x = 0; x < 10; x++) {
			System.out.println(getName() + ":" + x + ",日期:" + new Date());

			// 睡眠1秒中:1000毫秒
			try {
				Thread.sleep(1000);// 此方法本身就抛出一个异常!
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}






例7:stop()强迫线程停止执行

import java.util.Date;

public class StopDemo {

	public static void main(String[] args) {
		//创建线程类对象
		ThreadStop ts = new ThreadStop() ;
		ts.start() ;
		
		//如果3秒中不醒来,终止
		try {
			Thread.sleep(3000) ;
			ts.stop() ;		// 表示此方法过时,但还可以使用
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

// 自定义线程类
class ThreadStop extends Thread {
	
	@Override
	public void run() {
		System.out.println("开始执行了.."+new Date());
		
		//子线程进来之后,睡眠5秒中
		try {
			Thread.sleep(50000) ;
		} catch (InterruptedException e) {
			System.out.println("线程终止了...");
		}
		
		System.out.println("结束执行"+new Date());
	}
}








例8:interrupt()中断线程表示一种状态

import java.util.Date;

public class InterruptDemo {

	public static void main(String[] args) {
		//创建线程类对象
		ThreadInterrupt ti = new ThreadInterrupt() ;
		ti.start() ;
		
		//如果3秒中不醒来,中断
		try {
			Thread.sleep(3000) ;

			ti.interrupt() ;	//中断一种状态
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}



class ThreadInterrupt extends Thread {
	
	@Override
	public void run() {
		System.out.println("开始执行..."+new Date());
		
		//子线程进来之后,睡眠8秒中
		try {
			Thread.sleep(8000) ;
		} catch (InterruptedException e) {
			System.out.println("线程终止了...");
		}
		
		System.out.println("结束执行..."+new Date());
	}
}


【我的Java笔记】多线程_多线程的概述 & 实现方式_第6张图片






二、多线程的第二种实现方式


例:

public class MyThreadDemo {

	public static void main(String[] args) {

		// 1)创建MyRunnable实例对象
		MyRunnable my = new MyRunnable();

		// 2)创建线程类对象
		// 使用Thread类中的构造方法:public Thread(Runnable target,String name)
		Thread t1 = new Thread(my, "线程1");
		Thread t2 = new Thread(my, "线程2");

		// 启动线程
		t1.start();
		t2.start();
	}
}


// 自定义线程类实现Runnable接口
class MyRunnable implements Runnable {

	@Override
	public void run() {
		for (int x = 0; x < 5; x++) {
			System.out.println(Thread.currentThread().getName() + ":" + x);
		}
	}

}









你可能感兴趣的:(JavaSE)