Java多线程的简单学习及概述

多线程

多线程概述

一个进程之中可以有多个线程,每一个线程都会开辟一个不同的栈空间,在这个栈空间中,
同一个进程的不同线程共享资源。

认识线程

package thread;

public class ThreadTest01 {
	//除去垃圾回收线程之外,只剩下一个主线程
	public static void main(String[] args) {
	}
}

实现线程的第一种方式

package thread;

/**
 * 实现线程的第一种方式:
 * 编写一个类,继承java.lang.thread。重写run方法
 */
public class ThreadTest02 {

	public static void main(String[] args) {
		//新建一个分支线程
		MyThread myThread = new MyThread();
		//启动线程,这个方法会在JVM中开辟一个新的栈空间,这段代码执行完之后瞬间结束
		//启动成功会自动调用run方法,并且run方法在分支栈底部(压栈)
		//run方法与main方法都在各自进程的底部。
		myThread.start();
		
		for (int i = 0; i < 1000; i++) {
			System.out.println("主线程--->"+ i);
			}
	}
}
class MyThread extends Thread{

	@Override
	public void run() {
		for (int i = 0; i < 1000; i++) {
			System.out.println("分支线程--->"+ i);
		}
	}
}
//输出结果
/**
*主线程--->0
*分支线程--->0
*分支线程--->1
*主线程--->1
*分支线程--->2
*主线程--->2
*两个线程在抢同一个时间片
*/

实现线程的第二种方式


package thread;

public class ThreadTest03 {

	public static void main(String[] args) {
		//采用匿名内部类的方式创建一个线程,更高级的写法可以使用lombok表达式
		//编写一个类,实现java.lang.Runnable接口,实现run方法。
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 100; i++) {
					System.out.println("分支线程"+i);
				}
			}
		});
		t.start();
		for (int i = 0; i < 100; i++) {
			System.out.println("主线程"+i);
		}
	}
}

不使用匿名内部类的方式创建一个线程

package thread;
/**
 *不使用匿名内部类的方式实现一个线程,实现接口Runnable
 *传入所创建的线程中 
 */
public class ThreadTest07 {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		MyThread05 myThread05=new MyThread05();
		Thread t = new Thread(myThread05);
	}
}
class MyThread05 implements Runnable{
	@Override
	public void run() {
		// TODO 自动生成的方法存根
	}
}

实现线程的第三种方式

package thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
 *实现线程的第三种方式 
 *		实现Callable接口
 */
public class ThreadTest10 {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		//创建一个“未来任务类”对象
		FutureTask task= new FutureTask(new Callable() {
			@Override
			//此时线程可以执行一个任务,返回一个东西
			public Object call() throws Exception {
				return 300;
			}
		});
		Thread t = new Thread(task);
		t.start();
		//在主线程中回去未来任务线程中的返回值
		//get()方法的执行会导致“当前线程阻塞”
		Object obj =task.get();
		System.out.println(obj);
		//main方法这里的程序想要执行必须等待get()方法的结束
		//但是get()方法的执行可能需要很久
		System.out.println("hello world");
	}
}

返回当先线程名字

package thread;
/**
 * 1:修改某一个线程名字
 * 		t1.setName("t1线程")
 * 2:获取线程名字
 * 		t2.getName()
 * 3:获取当前线程对象(这是一个静态方法,返回一个Thread类型的对象)
 * 		Thread.currentThread()
 * 
 */		
public class ThreadTest04 {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		
		Thread currentThread= Thread.currentThread();
		System.out.println(currentThread.getName());
		
		MyThread2 t1 = new MyThread2();
		t1.setName("t1线程");//输出   t1线程
		t1.start();
		System.out.println(t1.getName());//Thread-0   默认线程名字
		
		MyThread2 t2 = new MyThread2();
		t2.setName("t2线程");//输出   t2线程
		t2.start();
		System.out.println(t2.getName());//Thread-1   默认线程名字
	}
}

class MyThread2 extends Thread{
	@Override
	public void run() {
		Thread currentThread= Thread.currentThread();
		System.out.println(currentThread.getName());
	}	
}

使线程睡眠的sleep方法

package thread;

import java.util.Date;
/**
 *1:静态方法:Thread.sleep(1000*5)
 *2:参数是毫秒
 *3:作用:让当前线程进入休眠,进入阻塞状态,放弃战友的cpu时间片,让给其他线程使用。 
 *
 *		当睡眠的代码出现在哪个线程中,哪个线程就会进入休眠,直至时间结束
 */

public class ThreadTest05 {

	public static void main(String[] args) throws InterruptedException {
		
		MyTherd03 t = new MyTherd03();
		
		Date date = new Date();
		System.out.println(date);   //Wed Oct 26 23:01:49 CST 2022
		
		//因为出现在主线程中,所以使主线程睡眠5秒
		t.sleep(1000*5);
		
		Date date2 = new Date();
		System.out.println(date2);  //Wed Oct 26 23:01:54 CST 2022
	}
}
class MyTherd03 extends Thread{
}

合理的终止一个线程

通过以下方式终止线程的优点:更加便于实际中使用,贴合现实。

package thread;

public class ThreadTest06 {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		MyThread4 r= new MyThread4();
		Thread t = new Thread(r);
		t.setName("t");
		t.start();
		//模拟5秒	
		try {
			Thread.sleep(1000*5);
		} catch (InterruptedException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		//通过一个布尔值控制一个线程的结束
		r.run=false;
	}
}
class MyThread4 implements Runnable{
	boolean run =true;
	@Override
	public void run() {
		// TODO 自动生成的方法存根
		for (int i = 0; i < 10; i++) {
			if (run) {
				System.out.println(Thread.currentThread().getName()+"---->"+i);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				}
			}else {
				
				//在这里可以对进程终止前的数据进行一系列操作(保存等)
				
				return;
			}
		}
	}
}

线程优先级

package thread;
/**
 *获取线程的优先级
 *线程最高优先级为10
 *		  默认优先级为5
 *		  最低优先级为1
 *可以通过静态方法获取当先线程 
 *		获取当先线程,并获得其优先级
 *		Thread.currentThread().getPriority()
 *		修改当前线程的优先级
 *		Thread.currentThread().setPriority(1);
 当一个线程的优先级低时,也会抢夺时间片,知识抢夺时间片的能力较低
 */
public class ThreadTest08 {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Thread.currentThread().setPriority(1);
		
		System.out.println(Thread.currentThread().getPriority());
	}
}

线程让位

Thread.yield();    这是一个静态方法
其在一瞬间做出让位到达就绪状态重新抢夺时间片
由官方文档可以得出:向调度程序提示当前线程愿意放弃其当前使用的处理器。
调度程序可以忽略此提示。
Yield是一种改进相对进展的启发式尝试否则会过度使用CPU。
其用途应结合详细的分析和基准测试确保它实际上具有期望的效果。

线程合并

package thread;

public class Threadtest09 {

	public static void main(String[] args) {
		System.out.println("main线程开始");
		Thread t = new Thread(new MyRunnable01());
		t.setName("t");
		t.start();
		//合并线程
		try {
			t.join(); //t合并到当前线程中,当前线程收到阻塞,直至t线程运行完毕,
			//两个线程都没有消失,知识当前线程收到阻塞
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("main线程结束");
	}
}

class MyRunnable01 implements Runnable{

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			try {
				Thread.sleep(1000/2);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"--->"+i);
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值