java中的线程概念以及线程创建

什么是线程

要想知道什么是线程,就要知道什么是进程。那什么是进程呢?进程指的是操作系统中一个程序的执行生命周期,也就是从他点击run程序创建中,直到程序运行结束退出。整个执行过程叫做进程。
那什么是线程呢。一个进程中肯定不止有一个线程,那么通俗的将进程的每一个子任务就是一个线程。

对比进程和线程

1.与进程相比,线程更加的轻量级。线程的创建、撤销相比较于进程的开销要小的多。
2.没有进程就没有线程,也就是说一个进程终止,其中的线程必然也将终止。
3.进程的操作系统资源调度的基本到位。进程可以独享资源,线程是OS任务执行的基本单位,线程依托于进程的资源,无法独立申请操作系统中的资源。而一个进程中的所有线程共享所有资源。

Thread的命名

1.在创建线程时通过调用构造传参设置线程名称。

public Thread(String name); 
public Thread(Runnable target,String name); 

2.创建好了以后设置线程名称
public final synchronized void setName(String name);
3.获取当前线程
public static native Thread currentThread();//通过Thread.currentThread()来获取当前线程
4.获取线程名称
public final String getName();

用java实现多线程

用java实现多线程有三种方式。1.通过继承Thread类实现多线程。2.通过实现Runnable接口实现多线程。3.通过实现Callable接口实现多线程。
1.继承Thread类实现多线程
thread类是线程操作的核心类,新建一个线程的方式就是new Thread().start()启动。我们通过覆写Thread()类中的run()方法来规定这个线程的具体操作。

class MyThread extends Thread{
	public MyThread(){
		super();
	}
	public void run(){
	for(int i=0;i<10;i++){
		Ststem.out.print(i+" ");
		}
	}
}
public class Test{
	public static void main(String[] args){
		MyThread  myThread = new MyThread();
		myThread.start();
 	}
}

你是否好奇为什么我们明明覆写的是run方法,却要调用Thread的start()方法呢?因为一个线程的创建不是仅仅调用我们写的这几行run代码就可以了。后台实际上JVM调用start方法后。先判断当前的状态。状态正常,调用start()(JVM)的native本地方法。也就是说这个本地文件不是java写的而是底层的.c文件,通过这个文件来准备做一些资源的调度,系统分配的操作。然后回调run方法,继续执行。
如果没有通过start操作,直接调用run方法,没有了本地方法的操作。他就只是个普通方法而已了。

2.实现Runnable接口实现多线程

class MyThread implements Runnable{
 public MyThread(){
  	super();
 }
 public void run(){
 	for(int i=0;i<10;i++){
 		 Ststem.out.print(i+" ");
  		}
 	}
}
public class Test{
 	public static void main(String[] args){
  	MyThread  myThread = new MyThread();
  	new Thread(muThread).start();
  	}
}

如果你通过Ctrl+B转到Thread类的具体实现,你可以发现Thread类也实现了Runnable接口。两个类公共实现一个接口,一个是我们真的要做的操作,一个是辅助我们实现。这就是典型的Java代理设计模型的思想啊。代理模式详解
实现Runable接口实现多线程的优点,我们通过new Thread创建对象,但是因为传递的实参都是一个我们MyThread实例化对象。也就说说回调的是同一个run方法。这样可以更好的描述共享资源的概念不是吗。

3.实现Callable实现多线程
如果我们希望线程执行完后带回一个返回值那么我们就需要实现Callable来实现多线程了。
于上面两个不同
Callable存放在util包下,我们通过覆写Callable的 V call()方法来实现多线程。
首先我们必须先理清Callabe和Thread的关系,因为每个线程都是通过Threadnew出来的。Callable可以作为FutureTask构造方法的参数类似于Runnable和Thread的关系,然后FutureTask实现了Runnable也就是说FutureTask可以作为Thread构造的参数。从而start->run->call方法实现我们定义的线程。我们通过task的get方法获取该线程的返回值。

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
class MyCallable implements Callable<String>{
	private Integer ticket=10;
	@Override
	public String call() {
		for(int i=0;i<10;i++){
			try {
				Thread.sleep(200);
			}catch (InterruptedException e) {
				e.printStackTrace();
				}
			System.out.println(Thread.currentThread()+":"+ticket--);
			}
		return "卖完了";
	}
}
public class Test{
	public static void main(String[] args) throws ExecutionException, InterruptedException {
		FutureTask<String> task = new FutureTask<>(new MyCallable());
		new Thread(task).start();
		System.out.println(task.get());
	}
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页