进程和线程的关系


1、一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有 一个线程(主线程)。
2、资源分配给进程,同一进程的所有线程共享该进程的所有资源。
3、线程在执行过程中需要协作同步。
4、CPU分给线程,即真正在处理机上运行的是线程。
5、线程是指进程内的一个执行单元,也是进程内的可调度实体,两者都是动态的概念。

线程和进程的区别

调度:线程是CPU调度和分配的基本单位,进程是系统资源分配和调度的基本单位。
并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可以并发执行,
一个进程至少有一个线程(单进程单线程),一个线程必须隶属于某个进程。
拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。
进程和线程最大的区别在于:进程是由操作系统来控制的,而线程是由进程来控制的。
线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换比进程切换的负担要小多个进程的内部数据和状态都是完全独立的,而多线程是共享一块内存空间和一组系统资源,有可能互相影响

进程

僵尸进程和孤儿进程
僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。如果父进程先退出 ,子进程被init接管,子进程退出后init会回收其占用的相关资源 ---是对系统资源的浪费,必须解决孤儿进程是一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作,没有什么危害。

public static void main(String[] args) throws IOException {
		Process p = Runtime.getRuntime().exec("cmd /c ipconfig/all");
		BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(),"GBK"));
		String ss=null;
		while((ss=br.readLine())!=null)
			System.out.println(ss);
		br.close();
	}

多次运行会发现执行顺序不一定相同,这就是多线程运行过程的不可重现性(执行的顺序不能保证),运行结果应该是一致的
Semaphore

public class Test1 {
	public static void main(String[] args) {
		//创建线程对象,然后调用start方法则可以启动一个线程,运行的代码就是run方法中的代码
		Thread t1 = new Thread() {
			public void run() {
				for(int i=0;i<10;i++) {
					System.out.println("左手");
					try {
						Thread.sleep(200);  //使当前线程休眠200ms
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};
		Thread t2 = new MyThread();
		t1.start();
		t2.start();
	}
}

class MyThread extends Thread {
	@Override
	public void run() {
		for(int i=0;i<10;i++) {
			System.out.println("右手");
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

注意事项

使用多线程并不能增加CPU的处理能力,也不一定会提升CPU的吞吐量,基于Internet的应用有必要使用多线程

线程组

主要通途:可以通过线程组,对线程组中一组线程进行统一管理,而不是一个一个的管理。注意显示线程时,如果线程显示为null表示线程已经消亡(执行结束)。

public class Test3 {
	public static void main(String[] args) {
		//创建线程组,指定名称yan1
		ThreadGroup group = new ThreadGroup("yan1");
		//创建线程,并指定线程所属的线程组
		Thread t1 = new Thread(group, () -> {
			for (int i = 0; i < 100; i++) {
				; //Thread[Thread-0,5,yan1]
				ThreadGroup gg=new ThreadGroup("yan1-"+i);
				new Thread(gg,()->{
					for(int k=0;k<100;k++);
				}).start();
			}
		});		
		t1.start();
		
		System.out.println(Thread.currentThread());//输出当前线程  main
		
		
		// 线程组的用途
		ThreadGroup tg = Thread.currentThread().getThreadGroup();
		System.out.println("ddd:"+tg);//java.lang.ThreadGroup[name=main,maxpri=10]
		int cc = tg.activeCount();// 获取所有活跃线程线程数
		System.out.println("ddd:"+cc);
		
		Thread[] list = new Thread[cc];
		tg.enumerate(list);// 获取所有获取线程,并存放在Thread[]中
		
		for (Thread temp : list)
			System.out.println("eee:"+temp);

		tg.list();// 以树装结构显示当前的所有线程组
		
		System.out.println("========================");
		cc=group.activeCount();
		System.out.println("yan1:"+cc);
		group.list();
	}
}

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐