java多线程(一)

上课学的java忘得差不多了,再看看多线程吧…

java语言实现了多线程机制,为什么不说是多进程的,因为进程概念是操作系统层面上的,不管OS有没有实现线程,进程都是资源调度的基本单位,线程只拥有很少的一部分资源,用于保证自己的正常运行。在一些没有实现多进程的系统上,就更不存在线程了。在多进程的系统中比如Windows操作系统,进程间的内存空间是互相独立的,数据不能直接共享,它的异步协作方式由进程中的线程来完成,这些线程共享进程所属内存来完成异步协作,java在这种操作系统上,表现的就是单进程多线程的方式。

  1. 线程的生命周期

    一个线程被实例化完成,到这个线程销毁,这整个过程。

  2. 线程的状态及状态转换

    – 创建态(新生态)

    – 就绪态

    – 运行态

    – 阻塞态

    – 销毁态(死亡态)

    在这里插入图片描述

    这张图是我在听一个网课(千锋教育)时截的图,不是自己画的,老师讲的很棒。

  3. 线程的创建

    package thread;
    
    public class ThreadCreate {
    
    	public static void main(String[] args) {
    		//1.继承Thread类,实现一个线程子类(自定义线程类)
    		MyThread mt = new MyThread();
    		mt.start();
    		
    		//2.通过Runnable 接口
    		/*Runnable r = new Runnable() {
    			public void run() {
    				
    			}
    		};*/
    		
    		//通过Runnable接口,使用lamada表达式
    		Runnable r2 = ()->{
    			for(int i = 0; i < 10; i++) {
    				System.out.println("线程2执行" + i);
    			}
    		};
    		Thread t2 = new Thread(r2);
    		t2.start();
    		
    		System.out.println("主线程执行...");
    	}
    }
    class MyThread extends Thread{
    	/**
    	 * 重写run方法
    	 * 将需要并发执行的任务写到run方法中
    	 */
    	@Override
    	public void run() {
    		for(int i = 0; i < 10; i++) {
    			System.out.println("MyThread线程中的逻辑" + i);
    		}
    	}
    	
    }
    

    需要注意的是mt.start();

    这个start方法是必要的,用来开启一个新的线程,来执行run中的逻辑;如果直接调用run()方法,则不会进入就绪状态,直接进入运行状态,没有并发。

  4. 线程的命名

    package thread;
    
    public class ThreadName {
    	public static void main(String[] args) {
    		//1.使用Thread类中的setName方法
    		Thread thread = new Thread();
    		thread.setName("线程1");
    		
    		//2.实例化一个线程的时候,通过构造方法对线程命名
    		Thread thread2 = new Thread("线程2");
    		Thread thread3 = new Thread(()-> {},
    									"线程3");
    		
    		//3.使用自定义的线程类,在实例化线程对象的同时,进行命名
    		Thread myThread2 = new Thread("Mythread");
    		
    		System.out.println(thread.getName());
    		System.out.println(thread2.getName());
    		System.out.println(thread3.getName());
    		System.out.println(myThread2.getName());
    	}
    }
    
    class MyThread2 extends Thread{
    	public MyThread2() {}
    	public MyThread2(String name) {
    //		super(name);
    		this.setName(name);
    	}
    	
    }
    

    运行结果:

    线程1
    线程2
    线程3
    Mythread

  5. 线程的休眠

    就是sleep()方法,它使线程进入阻塞状态,当给定时间到了以后,将恢复就绪状态,如果分配到了CPU,转换为执行状态,时间单位是毫秒,没再写新的线程,把Mythread2的run方法重写了一下。

    package thread;
    
    public class ThreadName {
    	public static void main(String[] args) {
    		//threadName();
    		threadSleep();
    	}
    	private static void threadSleep() {
    		Thread mThread2 = new MyThread2();
    		mThread2.start();
    	}
    	private static void threadName() {
    		//1.使用Thread类中的setName方法
    		Thread thread = new Thread();
    		thread.setName("线程1");
    		
    		//2.实例化一个线程的时候,通过构造方法对线程命名
    		Thread thread2 = new Thread("线程2");
    		Thread thread3 = new Thread(()-> {},
    									"线程3");
    		
    		//3.使用自定义的线程类,在实例化线程对象的同时,进行命名
    		Thread myThread2 = new Thread("Mythread");
    		
    		System.out.println(thread.getName());
    		System.out.println(thread2.getName());
    		System.out.println(thread3.getName());
    		System.out.println(myThread2.getName());
    	}
    }
    
    class MyThread2 extends Thread{
    	public MyThread2() {}
    	public MyThread2(String name) {
    //		super(name);
    		this.setName(name);
    	}
    	@Override
    	public void run() {
    		for(int i = 0; i < 10; i++) {
    			try {
    				Thread.sleep(1000);	//线程休眠1秒钟
    				System.out.println(i);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    	
    }
    
  6. 线程的优先级

    设置的优先级,只是修改这个线程可以抢到CPU时间片的概率并不是优先级高的线程一定能抢到CPU,优先级的设置,是一个0-10的整数;如果未设置,优先级默认为5。

    package thread;
    
    public class ThreadName {
    	public static void main(String[] args) {
    		threadPriority();
    	}
    	
    	private static void threadPriority() {
    		Runnable r = ()->{
    			for (int i = 0; i < 10; i++) {
    				System.out.println(Thread.currentThread().getName() + ":" + i);
    			}
    		};
    		
    		Thread r1 = new Thread(r, "线程1");
    		Thread r2 = new Thread(r, "线程2");
    		
    		//设置优先级
    		r1.setPriority(1);
    		r2.setPriority(10);
    		
    		r1.start();
    		r2.start();
    	}
    }
    
  7. 线程礼让

    让当前的运行态的线程释放自己的CPU资源,由运行状态,返回就绪态

    执行yield方法,当前正在执行的线程让出CPU,成为就绪态,重新等待CPU分配。

    需要注意的是就算当前线程让出CPU,它可能又会被CPU分配到资源,比如说下面的例子,当i=3 的时候,线程礼让,但是这个线程礼让后可能又会分配到CPU,继续执行i=4。

    package thread;
    
    public class ThreadName {
    	public static void main(String[] args) {
    		threadYield();
    	}
    	private static void threadYield() {
    		Runnable r = ()->{
    			for (int i = 0; i < 10; i++) {
    				System.out.println(Thread.currentThread().getName() + ":" + i);
    				if(i == 3) {
    					Thread.yield();	//线程礼让
    				}
    
    			}
    		};
    		
    		Thread r1 = new Thread(r);
    		Thread r2 = new Thread(r);
    		r1.start();
    		r2.start();
    	}
    }
    

    一种不出乎意料的结果:

    Thread-0:0
    Thread-1:0
    Thread-1:1
    Thread-1:2
    Thread-1:3
    Thread-0:1
    Thread-0:2
    Thread-0:3
    Thread-1:4
    Thread-1:5
    Thread-1:6
    Thread-1:7
    Thread-1:8
    Thread-0:4
    Thread-0:5
    Thread-0:6
    Thread-0:7
    Thread-1:9
    Thread-0:8
    Thread-0:9

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值