欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【多线程】线程状态,线程组,线程锁,线程中断

程序员文章站 2022-05-05 16:33:44
...

进程拥有一个完整的虚拟地址空间,不依赖于线程而独立存在;

线程是进程的一部分,没有自己的地址空间,与进程内的其他线程一起共享分配给该进程的所有资源一个线程可以创建和撤消另一个线程,线程有时被称为轻量级进程(Lightweight Process,LWP)程序执行流的最小单元,一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。

线程有创建,可运行,运行中,阻塞,死亡五种状态。

【多线程】线程状态,线程组,线程锁,线程中断


1.创建状态
使用new运算符创建一个线程后,该线程仅仅是一个空对象,系统没有分配资源,称该线程处于创建状态(new thread)
2.可运行状态
使用start()方法启动一个线程后,系统为该线程分配了除CPU外的所需资源,使该线程处于可运行状态(Runnable)
3.运行中状态
Java运行系统通过调度选中一个Runnable的线程,使其占有CPU并转为运行中状态(Running).此时,系统真正执行线程的run()方法.
4.阻塞状态
一个正在运行的线程因某种原因不能继续运行时,进入阻塞状态(Blocked)
5.死亡状态

线程结束后是死亡状态(Dead)

线程可以通过三种方式创建 实现Runnable接口,实现Callable接口和继承Thread类(Thread类也是实现了Runnable接口)

【多线程】线程状态,线程组,线程锁,线程中断

第一种:通过实现Runnable接口创建线程

public class RunnableDemo2 implements Runnable {
     private Thread t;
     private String ThreadName;
     public RunnableDemo2(String ThreadName){
    	 this.ThreadName=ThreadName;
     }
     
	@Override
	public void run() {
		for(int i=0;i<4;i++){
			try {
				System.out.println(ThreadName+" 拿到"+i);
				Thread.sleep(2000);
				
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
     public static void main(String[] args) {
		Thread t1=new Thread(new RunnableDemo2("线程1 "));
		Thread t2=new Thread(new RunnableDemo2("线程2 "));
		t1.start();
		t2.start();
	}
}

第二种:通过继承Thread类创建线程

public class ThreadDemo1 extends Thread{

	 private String ThreadName;
	 private Thread t;
	 
	 public ThreadDemo1(String ThreadName){
		 this.ThreadName=ThreadName;
	 }

	@Override
	public void run() {
		for(int i=0;i<9;i++){
		  System.out.println(ThreadName+"执行");
		  try {
			Thread.sleep((int)(Math.random()*30));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		}
	}
	 
	 public static void main(String[] args) {
		  Thread t1=new Thread(new ThreadDemo1("线程A"));
		  Thread t2=new Thread(new ThreadDemo1("线程B"));
		  t1.start();
		  t2.start();
	}	 
}

【多线程】线程状态,线程组,线程锁,线程中断【多线程】线程状态,线程组,线程锁,线程中断


第三种

//通过实现Callable接口来创建线程
public class CallableThreadTest implements Callable<Integer>{
	  public static void main(String[] args) {
		  
		  CallableThreadTest ctt=new CallableThreadTest();
	      FutureTask<Integer> ft = new FutureTask<Integer>((Callable<Integer>) ctt);
		 for(int i=0;i<30;i++){
			    System.out.println(Thread.currentThread().getName()+"的循环变量i的值");
			    //开启线程,传入FutureTask对象
				 new Thread(ft,"有返回值的线程").start();
		 } 
		 //执行完返回子线程的值
	      try {
			System.out.println("子线程的返回值:"+ft.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		 }
       }

	@Override
	public Integer call() throws Exception {
		int i=0;
		for(;i<50;i++){
			System.out.println(Thread.currentThread().getName()+""+i);
		}
		return i;
	}
}
【多线程】线程状态,线程组,线程锁,线程中断

线程组:线程组把多个线程集成为一个对象,通过线程组可以同时对其中的多个线程进行操作

线程默认情况下属于main线程组  

创建线程组:

对线程组进行操作的方法如下所示: 
 resume(); //使被挂起的当前组内的线程恢复到可运行状态 
 etDaemon (boolean daemon); //指定一个线程为当前线程组的监护线程 
 setMaxPriority(int pri); //设置当前线程组允许的最大优先级 
 stop(); //终止当前线程组中所有线程 
 suspend(); //挂起当前线程组中所有线程 

 toStrinng(); //将当前线程组转换为String类的对象


 public static void main(String[] args) {
		ThreadGroup group1=new ThreadGroup("group1");  //创建线程组group1
		ThreadGroup group2=new ThreadGroup(group1,"group2"); //创建线程组group2,并将group2加入线程组group1
		ThreadGroup group3=new ThreadGroup("group3");  
		Thread thread1=new Thread(group2,new Mythread("线程 1"));
	    Thread thread2=new Thread(group2,new Mythread("线程 2"));
	    Thread thread3=new Thread(group3,new Mythread("线程 3"));
	    Thread thread4=new Thread(group3,new Mythread("线程 4"));
	    
	    thread1.start();
	    thread2.start();
	    thread3.start();
	    thread4.start();
	    while (Thread.currentThread().getThreadGroup().activeCount() != 1) {  
	        Thread.yield();  
	   }         
	           System.err.println("over");  
	       }  
	   
	 }
	

【多线程】线程状态,线程组,线程锁,线程中断

【多线程】线程状态,线程组,线程锁,线程中断


[线程同步]

银行存取钱时,不能对同一账户同时进行存和取的操作,只能一个操作进行完成才能进行另一个操作。

//储蓄账户
 class BlankSaving {
	private static int money=10000;
    public void add(int i){
	money=money+i;System.out.println("Husband 向银行存入了 [¥"+i+"]");
	}
    public void get(int i){
	money=money-i;System.out.println("Wife 向银行取走了 [¥"+i+"]");
	if(money<0)System.out.println("余额不足!"); 
	}
    public int showMoney(){
	return money;
	}
   } 

   class Operater implements Runnable{
	String name;
	BlankSaving bs;
	public Operater(BlankSaving b,String s){
		name=s;
		bs=b;
		}
	public synchronized static void oper(String name,BlankSaving bs){
		if(name.equals("husband")){
			try{for(int i=0;i<10;i++){
				Thread.currentThread().sleep((int)(Math.random()*300));
				bs.add(1000);}
			  }catch(InterruptedException e){}
		}
		else{
					try{for(int i=0;i<10;i++){
						Thread.currentThread().sleep((int)(Math.random()*300));
						bs.get(1000);}
					}catch(InterruptedException e){}}
		}
	public void run(){
		oper(name,bs);}
	}
    
public class BankTest {
	public static void main(String[] args)throws InterruptedException{
		BlankSaving bs=new BlankSaving();
		Operater o1=new Operater(bs,"husband");
		Operater o2=new Operater(bs,"wife");
		Thread t1=new Thread(o1);
		Thread t2=new Thread(o2);
		t1.start();
		t2.start();
		Thread.currentThread().sleep(500);
		}
	}


未加synchronized之前执行结果

【多线程】线程状态,线程组,线程锁,线程中断

加了synchronized之后

【多线程】线程状态,线程组,线程锁,线程中断

【多线程】线程状态,线程组,线程锁,线程中断


【线程挂起和唤醒】

class MyThread_1 extends Thread{
	Object lockName;
	public MyThread_1(Object lockName){
		this.lockName=lockName;
		}
	public void run(){
		try{
			synchronized(lockName){
				System.out.println("线程1:“我运行了”");
				lockName.wait(); //将线程对象挂起
				System.out.println("线程1 :“我被唤醒啦。。。(由阻塞变成可运行状态)”");
				}}catch(InterruptedException e){}
		   }}

    class MyThread_2 extends Thread{
    	Object lockName;
    	public MyThread_2(Object lockName){
    		this.lockName=lockName;
    		}
    	public void run(){
    			synchronized(lockName){
    				System.out.println("线程2:“我运行了”");
    				lockName.notify(); //唤醒线程1 
    				}
    			}
    	}
  

public class MyThread{ 
	   public static void main(String[] args){
		   int[] in=new int[0];//java中创建一个0长度的数组来充当锁更加高效
		   //notice
		   MyThread_1 t1=new MyThread_1(in);
		   MyThread_2 t2=new MyThread_2(in);
		   t1.start();
		   t2.start();
		   }
	   }

执行结果;

【多线程】线程状态,线程组,线程锁,线程中断

线程中断 Interrupt

注意:不是停止线程,而是在线程等待(死锁)的时候抛出一个InterruptedException异常,如果我们要停止该线程直接捕获该异常进行return即可

【多线程】线程状态,线程组,线程锁,线程中断

【多线程】线程状态,线程组,线程锁,线程中断