java基础笔记(15)线程调度方法:sleep,yield,优先级,priority,join,interrupt,setDaemon守护线程,线程生命周期,线程同步

线程调度方法
1.sleep方法
sleep方法在睡眠的时候, 是会释放cpu , 睡眠期间不会抢cpu的
即使睡眠期间没有其他线程占用cpu, 此线程也需要等到睡醒才去抢占cpu

public class Test {
    
    
	public static void main(String[] args) {
    
    
		MyThread t = new MyThread();
		t.start();			
		System.out.println("heheheh");		
		System.out.println("hhhhhhhhh");
	}
}
class MyThread extends Thread{
    
    	
	@Override
	public void run() {
    
    
		for (int i = 0; i < 20; i++) {
    
    
			try {
    
    
				Thread.sleep(1000);
			} catch (InterruptedException e) {
    
    
				// TODO Auto-generated catch block
				e.printStackTrace();
			}			
			System.out.println("子线程"+i);
		}
	}
}

在这里插入图片描述
2.yield 方法
会释放cpu,但是随手就抢

线程的优先级: 仅仅代表线程的重要或者紧急程度,不代表谁先执行
优先级范围1~10,默认为5,对应的数值越大,说明优先级越高,这个方法的设置一定要在start之前
线程的优先级低并不意味着争抢不到时间片,只是抢到时间片的概率比较低而已
Priority 仅仅能代表重要或者紧急程度, 不能代表执行的顺序
sleep和yeild的区别:

  1. 都会释放cpu ,但是sleep必须是等到设定的时间以后才会去抢占cpu
    yield释放以后迅速的抢占cpu
  2. sleep释放了cpu以后,剩下所有的线程都可以公平竞争抢占cpu
    yield释放了cpu以后,只允许和自己优先级相同或者比自己优先级高的线程去抢占cpu
public class Test2 {
    
    
	public static void main(String[] args) {
    
    
		MyThread2 thread2 =new MyThread2();
		thread2.start();		
		for (int i = 0; i < 20; i++) {
    
    
			System.out.println("主线程");
		}		
	}
}
class MyThread2 extends Thread{
    
    	
	@Override
	public void run() {
    
    
		for (int i = 0; i < 20; i++) {
    
    
			Thread.yield();
			System.out.println("子线程"+i);
		}
	}
}

在这里插入图片描述

3.join方法
插入到当前线程前面,和当前线程合并在一起
调用者做插队的事情,join写到了哪个线程里面 就会插队到哪个线程前面

public class Test4 {
    
    
	public static void main(String[] args) {
    
    
		MyThread4 thread4 = new MyThread4();
		thread4.start();		
		try {
    
    
			thread4.join();
		} catch (InterruptedException e) {
    
    			
			e.printStackTrace();
		}
		for (int i = 0; i < 20; i++) {
    
    
			System.out.println("主线程"+i);
		}
	}
}
class MyThread4 extends Thread{
    
    
	@Override
	public void run() {
    
    		
		MyThread5 thread5 = new MyThread5();
		thread5.start();		
		try {
    
    
			// thread5调用join就是thread5要插队
			// 写在哪个线程里面, 就是插队到哪个线程前面
			thread5.join();
		} catch (InterruptedException e) {
    
    
			
			e.printStackTrace();
		}
		for (int i = 0; i < 20; i++) {
    
    
			System.out.println("444"+Thread.currentThread().getName()+i);
		}
	}	
}
class MyThread5 extends Thread{
    
    
	@Override
	public void run() {
    
    
		for (int i = 0; i < 20; i++) {
    
    
			System.out.println("555"+Thread.currentThread().getName()+i);
		}
	}
}

在这里插入图片描述
4.线程的生命周期
在这里插入图片描述
5.守护线程
如果子线程是守护线程,默认为false, 为前台线程, 设置成true后台线程
如果想要设置成为守护线程一定要在start以前

public class Test5 {
    
    
	public static void main(String[] args) {
    
    
MyThread6 t = new MyThread6();	
		t.setDaemon(true);
		t.start();		
		for (int i = 0; i < 20; i++) {
    
    
			System.out.println("主线程");
		}		
	}
}
class MyThread6 extends Thread{
    
    	
	@Override
	public void run() {
    
    
		for (int i = 0; i < 200; i++) {
    
    
			System.out.println("子线程"+i);
		}
	}
}

在这里插入图片描述

6.interrupt
以抛异常的方式打断正在sleep中的线程,会产生一个InterruptedException 这个异常
stop()过时了,不建议使用

public class Test6 {
    
    
	public static void main(String[] args) {
    
    
		MyThread7 thread7 = new MyThread7();
		thread7.start();
		thread7.interrupt();
		try {
    
    
			Thread.sleep(2000);
		} catch (InterruptedException e) {
    
    
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		// 过时了,不建议使用
		thread7.stop();
	}
}
class MyThread7 extends Thread{
    
    	
	@Override
	public void run() {
    
    
		System.out.println("困了");
		try {
    
    
			Thread.sleep(60000000);
		} catch (InterruptedException e) {
    
    
			System.out.println("打醒了");
		}
		System.out.println("醒了");		
	}
}

在这里插入图片描述

7.线程的方法
线程对象.setName();
Thread.currentThread().getName();
Thread.sleep();
线程对象.priority();
线程对象.join();
线程对象.setDaemone();
Thread.yield();
线程对象.interrupt();

8.线程同步
synchronized :同步的关键字
在同步执行完这段代码之前,其他线程不允许进来执行
需要一把锁,必须是唯一的
互斥锁
锁对象可以是任意数据类型
任意锁
设定范围:
1.使用同步代码块
2.同步方法
想要实现线程同步,前提跳进

    1. 拥有共享资源
    1. 至少要拥有两个以及以上的线程
  • 如何实现线程同步代码块
    1. 锁 唯一的锁
    1. 确定哪些代码需要同步
    1. synchronized (this){} 用同步代码块把代码包裹起来
public class Ticket implements Runnable{
    
    
int ticket  = 100;	
	// 一把锁  是唯一的  只能有一个对象
	//Object obj = new Object();	
	@Override
	public void run() {
    
    
		// ticket = 1
		while(true){
    
    
		// 同步的关键字  num = 1
			synchronized (this){
    
    // this 指代的是Ticket的对象, ticket只能创建一次对象  锁是唯一的	
				if(ticket>0){
    
    
					ticket--;//
					System.out.println(Thread.currentThread().getName()+"还剩"+ticket);
				}else{
    
    
					break;
				}
			}		
		}		
	}
}
public class Test2 {
    
    
	public static void main(String[] args) {
    
    
				Ticket ticket = new Ticket();				
				Thread t = new Thread(ticket, "窗口一");
				Thread t2 = new Thread(ticket, "窗口二");
				Thread t3 = new Thread(ticket, "窗口三");
				Thread t4 = new Thread(ticket, "窗口四");				
				t.start();
				t2.start();
				t3.start();
				t4.start();				
			}
		}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Echoxxxxx/article/details/112892549
今日推荐