Java的多线程

1.线程和进程

 进程:一个正在运行的程序就是进程

 线程:一个进程中有很多线程

 每一个线程相当于一个执行的任务

 开启一个线程相当于开启了一个cpu的执行路径

 CPU在执行多个线程的时候是随机的,跟线程的优先级有关

 分时调度 CPU会在多个线程中随机切换


标准的单线程程序

特点:程序忧伤至下依次执行(一个执行完才执行下一个)

好处:绝对安全  不牵扯到操作共享数据

弊端:效率不高

public static void main(String[] args) {
		add();
		delete();
		System.out.println("执行完");
		
	}
	public static void add() {
		for (int i = 0; i < 100; i++) {
		System.out.println("add---"+i);
		}
	}
	public static void delete() {
		for (int i = 0; i < 100; i++) {
		System.out.println("delete---"+i);
		}
	}

2.主线程

多线程的程序除了主线程外 一般都叫子线程

一个程序只有一个主线程 

main函数就是一个线程 是主线程

主线程(叫main的函数)是如何执行的

jvm调用main函数-->cpu就为叫main的函数开辟一个执行路径-->相当于在这个执行路径中执行main函数的代码

Thread线程类(开辟一个主线程以外的线程  子线程)

1.创建一个thread类的子类

2.重写run方法  run方法就是你要线程执行的代码

3.调用start方法 开启线程 (不能重复开启)

子线程默认名字 thread-0

class SubThread extends Thread{
	@Override
	public void run() {
       }
}

创建一个子线程

开启多个线程时 多个线程会同时执行 并且相对独立的执行单元

主线程出现异常 不影响子线程

SubThread subThread=new SubThread();
		subThread.start();
SubThread  subThread1=new SubThread();
		subThread1.start();

3.线程的名字

public static void main(String[] args) {
		NameThread nameThread=new NameThread("haha");
		//设置线程名字
		// nameThread.setName("线程---1");	
		System.out.println(nameThread.getName());
		//获取主线程的名字
	        Thread currentThread= Thread.currentThread();
	         System.out.println(currentThread.getName());
	}
}
class NameThread extends Thread{
	//构造方法
	public NameThread() {	
	}
	public NameThread(String name) {
	//调用父类的构造方法
		super(name);
	}
	@Override
	public void run() {
		//获取的是子线程的对象
		Thread currentThread = Thread.currentThread();
		System.out.println("我是子线程"+currentThread.getName());
		//简写:
		//System.out.println(Thread.currentThread().getName());
		//获取线程的名字
		System.out.println(getName());
	}

创建一个线程类 提供又参无参 set/get方法

class MyThread extends Thread{
	//定义了自己的name属性
	private String  name;
	public MyThread() {
	}
	//有参
	//1.给父类name赋值
	//2.给本类的name赋值
	public MyThread(String name,String myname) {
		super(name);
		this.name=myname;
	}
	//set/get  父类中使用final修饰了该方法 不能被子类重写
	//修改方法名
	public void setMyName(String name) {
		this.name=name;
	}
	public String  getMyName() {
	return this.name;
	}
	@Override
	public void run() {
	
	}

 创建一个线程 相当于 cpu开启一个独立执行路径

 相当于开辟一个独立的方法栈 专门运行子线程的方法

4.线程的创建方式2

使用接口实现类的方法来创建

public static void main(String[] args) {
	RunnableImpl runnableImpl=new RunnableImpl();
	Thread  thread=new Thread(runnableImpl);
	thread.start();	
}
}
class RunnableImpl implements Runnable{
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
		System.out.println(Thread.currentThread().getName()+"--"+i);
		}
	}
5.匿名内部类的方法创建线程

匿名内部类创建出来的对象是该类的子类对象


new Test() {};  相当于test的子类对象

并且可以在后面的大括号例重写父类中的方法

public static void main(String[] args) {
	}
	Test test=new  Test() {
	@Override
	public void fun() {
	System.out.println("我是匿名内部中重写的fun方法");
	                  }
	};
		test.fun();
	}
class Test{
	public void fun() {
	System.out.println("我是test中的fun方法");	
	}

直接创建接口类的实现类对象

注意:这种方法new后面跟的是父类名 

但是创建出来的对象 确实子类或实现类的对象

public static void main(String[] args) {
		TestInter testInter=new TestInter() {	
		@Override
		public void fun() {
		System.out.println("我是实现类的fun方法");
			}
		};
		testInter.fun();
	}

interface TestInter{
	public abstract void fun();
}

利用匿名内部类方式

给集合中3个学生对象 按年龄进行排序(比较器)

public static void main(String[] args) {
	Comparator<Student> comparator=new Comparator<Student>() {
		@Override
		public int compare(Student o1, Student o2) {		
		return o1.getAge()-o2.getAge();
		}
	};
		TreeSet<Student>set=new TreeSet<>(comparator);
		set.add(new Student("aa", 16));
		set.add(new Student("aa", 18));
		set.add(new Student("aa", 6));
		System.out.println(set);
}

上面代码一起写

TreeSet<Student>set2=new TreeSet<>(new Comparator<Student>() {
			@Override
			public int compare(Student o1, Student o2) {
			
				return o1.getAge()-o2.getAge();
			}
		});

1(thread子类的方式)

Thread thread=new Thread() {
			@Override
			public void run() {
			System.out.println("子线程执行的方法");
			}
		};
		thread.start();

2(接口实现类的方式)

Runnable runnable=new Runnable() {	
			@Override
			public void run() {
			System.out.println("子线程方法");
			}
		};
		Thread thread3=new Thread(runnable);
		thread3.start();

3方式2的两步写一起

Thread thread2=new Thread(new Runnable() {
			
			@Override
			public void run() {
				System.out.println("子线程方法");
			}
		});
		thread2.start();

6.线程状态(6种)

新建状态(new Thread())

运行状态(start())

死亡状态(run方法运行完毕)

受阻塞状态(cpu为执行该线程时)

休眠状态(sleep方法 休眠时间过了 恢复)

等待状态(wait notify)



线程调用start()方法就一定会变成运行状态吗?

不一定,调用start方法是表示该方法被cpu执行,但是cpu不一定运行,所以不一定变成运行状态,等待cpu的执行.这种状态叫受阻塞状态

主线程休眠:

参数时休眠时间单位毫秒

卡主主线程一秒

休眠时间结束会自动醒来

Thread.sleep(1000);

父类中的run方法没抛异常,子类只能try-catch处理

try {
		Thread.sleep(1000);
	} catch (InterruptedException e) {		
	}










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值