Java多线程具体代码实战


首先,我们需要明白在Java中,多线程就是一个类或者一个程序执行或者管理多个线程执行任务的能力,线程总是处于5种状态之中,分别是:创建,可运行,运行中,阻塞,死亡。
创建:使用 new 运算符后,该线程仅仅是一个空对象,系统没有分配资源,该线程处于创建状态(new thread)
可运行:使用start()方法启动一个线程后,系统为该线程分配了除了CPU外的所需资源,该线程处于可运行状态(Runnable)
运行:Java运行系统通过调度选中其中一个Runnable的线程,使其占有CPU并转为运行中状态(Running)时。系统真正执行线程的run()方法。
阻塞:一个正在运行的线程因某种原因无法继续运行时,进入阻塞状态(Blocked)
死亡:线程结束后是死亡状态(Dead)

在java中进程分成普通线程和守护线程,区别在于结束的方式,普通线程和守护线程可以以并行的方式执行,但是当所有的普通线程都结束时,守护线程也会相应停止。可以使用**setDeamon(boolean)**方法来将普通线程变成守护进程

join()函数:thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。

##########################################################################################
接下来,我将通过实例来进一步细说线程及相关知识

通过继承Thread创建一个线程

主要包含两个类,HelloMain.java和HelloThread.java,其中HelloThread类继承了Thread类并重写了它的run()方法,HelloMain中启动HelloThread。

HelloMain.java

package com.caigentan.java.thread;  
public class HelloMain {     
	public static void main(String[] args) throws InterruptedException{         
		int idx = 1;         
		for(int i=0;i<2;i++){             
			System.out.println("Main thread running " + idx++);             
			Thread.sleep(2101);         
		}         
		HelloThread helloThread = new HelloThread();         
		helloThread.start();          
		for (int i = 0; i < 3; i++){             
			System.out.println("Main Thread running " + idx++);             
			Thread.sleep(2101);         
		}        
		 System.out.println("=====> Main thread stopped");    
	} 
} 

HelloThread.java

package com.caigentan.java.thread;  
public class HelloThread extends Thread{     
	@Override     
	public void  run() {         
		int index = 1;         
		for(int i = 0;i<10;i++){             
			System.out.println("   - HelloThread Running" + index++);             
			try {                 
				Thread.sleep(1030);             
			}catch (InterruptedException e){              
			}        
		 }         
		 System.out.println("====> HelloThread stopped");     
	} 
}

运行效果如下:
在这里插入图片描述

守护进程

java中进程分成普通线程和守护线程,区别在于结束的方式,普通线程和守护线程可以以并行的方式执行,但是当所有的普通线程都结束时,守护线程也会相应停止。可以使用**setDeamon(boolean)**方法来将普通线程变成守护进程。
此处的实验分成3个,分别是DeamonTest.java,DeamonThread.java和NoDeamonThread.java

DeamonTest.java

package com.caigentan.java.thread.deamon;

public class DeamonTest{
    public static void main(String[] args) {
        System.out.println("\nMain Thread Start.. \n");
        Thread deamonThread = new DeamonThread();
        deamonThread.setDaemon(true);
        deamonThread.start();

        new NoDeamonThread().start();
        try{
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("\nMain Thread end..\n");
    }
}

DeamonThread.java

package com.caigentan.java.thread.deamon;  
public class DeamonThread extends Thread{     
	@Override     
	public void run() {         
		int count = 0;         
		while(count<100){             
			System.out.println("Hello From DeamonThread" + count++);             
			try {                 
				Thread.sleep(2000);            
			} catch (InterruptedException e) {                 
				e.printStackTrace();             
			}         
		}         
		System.out.println("DeamonThread end..");     
	} 
}

NoDeamonThread.java

package com.caigentan.java.thread.deamon;  
public class NoDeamonThread extends Thread{     
	@Override     
	public void run() {         
		int i = 0;         
		while(i<10){             
			System.out.println(" -Hello From NoDeamon Thread" + i++);             
			try {                 
				Thread.sleep(1000);             
			} catch (InterruptedException e) {                 
				e.printStackTrace();             
			}         
		}         
		System.out.println("\n====> NoDeamon Thread ending\n");     
	} 
}

效果如下,可以看到,当程序中所有的普通进程都停止时,守护进程也会立即停止。在java中守护进程的典型例子就是GC机制,当所有程序都停止,GC机制也会自动停止
在这里插入图片描述

线程池

线程池是管理线程的高级技术,通常它提供了如下几个功能
●通过对线程的管理,更加合理的调配资源。通常,线程池里维护着一组空闲线程,并向外 提供,根据系统繁忙程度动态増加或减少空闲线程的数量。比较高级的还提供了自动检测 异常线程的功能
●通过维护池中即存线程,可以节省创建线程的开销,尤其是对于 Web server这类处理频繁 而处理过程又比较快的程序,创建线程的开销是不能忽略的。
此处使用两个程序进行说明,普通线程ExecutorServiceDemo1.java 和调用类ExecutorServiceThread.java。

ExecutorServiceDemo1.java

package com.caigentan.java.thread;  
public class ExecutorServiceDemo1 extends Thread{     
	private String threadName;     
	private int count;      
	public ExecutorServiceDemo1(String threadName, int count){         
		this.threadName = threadName;         
		this.count = count;     
	}      
	
	@Override     
	public void run() {         
		int i = 0;         
		while(i<count){             
			System.out.println("thread " + this.threadName + " start! " + i++);             
			try {                 
				Thread.sleep(1024);             
			} catch (InterruptedException e) {                 
				e.printStackTrace();             
			}         
		}     
	} 
}

ExecutorServiceThread.java

package com.caigentan.java.thread;  
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors;  

public class ExecutorServiceThread {       
	public static void main(String[] args) {         
		System.out.println("Main thread starting...");         
		//创建线程池         
		ExecutorService exec = Executors.newFixedThreadPool(3);          
		ExecutorServiceDemo1 hello1 = new ExecutorServiceDemo1("hello1",2);         
		ExecutorServiceDemo1 hello2 = new ExecutorServiceDemo1("hello2",2);         
		ExecutorServiceDemo1 hello3 = new ExecutorServiceDemo1("hello3",2);         
		while (true) {             
			exec.execute(hello1);             
			exec.execute(hello2);             
			exec.execute(hello3);             
			try {                 
				Thread.sleep(2030);             
			} catch (InterruptedException e) {                 
				e.printStackTrace();             
			}         
		} 
	} 
}

当 ExecutorService exec = Executors.newFixedThreadPool(3);
在这里插入图片描述
可以看到每次可以同时运行3个线程

当 ExecutorService exec = Executors.newFixedThreadPool(2);

可见每次只能同时运行2个线程

join()

join()表示运行在当前运行的线程中插入另外一个线程,并且在插入的线程运行结束前不会运行下面的线程。
此处使用2个文件来说明,分别是JoinTest.java和JoinThread.java

JoinTest.java

package com.caigentan.java.thread.join; 
public class JoinTest {     
	public static void main(String[] args) throws InterruptedException {         
		System.out.println("\n==> Main thread starting..\n");         
		Thread joinThreadA = new JoinThread("joinThreadA",2);         
		Thread joinThreadB = new JoinThread("joinThreadB",3);          
		Thread noJoinThreadC = new JoinThread("joinThreadC",5); 
		//        noJoinThreadC.setDaemon(true);          
		joinThreadA.start();         
		joinThreadB.start();         
		noJoinThreadC.start();          

		joinThreadA.join();         
		joinThreadB.join();          
		
		System.out.println("Hello from main thread...");          
		System.out.println("Thread A isLive? " + joinThreadA.isAlive());         
		System.out.println("Thread B isLive? " + joinThreadB.isAlive());         
		System.out.println("Thread C isLive? " + noJoinThreadC.isAlive());          
		System.out.println("\n==> Main Thread end!\n");     
	} 
}

JoinThread.java

package com.caigentan.java.thread.join;  
public class JoinThread extends Thread{     
	private String threadName;     
	private int count;      

	public JoinThread(String threadName,int count){         
		this.threadName = threadName;         
		this.count = count;     
	}      

	@Override     
	public void run() {         
		for (int i=1;i<count;i++){             
			System.out.println("Hello From " + this.threadName + " " + i);             
			try {                 
				Thread.sleep(2000);             
			} catch (InterruptedException e) {                 
				e.printStackTrace();             
			}         
		}         
		System.out.println("===>Thread " + threadName + " end\n");     
	}  
}

效果如下:
在这里插入图片描述
关于常用的多线程目前就到此,还有一些高级使用代日后使用到了我再来更新!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值