java多线程:2 创建线程

版权声明:转载请标明来源 https://blog.csdn.net/u010652576/article/details/78569325

如何创建一个多线程:

Java提供了java.lang.Thread类,这就是线程的定义类,包含了:线程的优先级,线程id、线程状态等线程的基本信息。
通过Thread类的说明,可以知道创建线程的两种方式:1 extends Thread类,2 implements Runnable接口

1 继承Thread类

package com.thread;

public class ThreadCreate {
	public static void main(String[] args) {
		Thread t = new MyThread(new User("jkf"));
		t.start();
	}
}

class MyThread extends Thread{
	private User u;
	public MyThread(User u){
		this.u = u;
	}
	//重写run方法
	public void run(){
		System.out.println("this is my Thread "+Thread.currentThread().getName());
		u.printName();
	}
}
class User{
	private String name;
	public User(String name){
		this.name=name;
	}
	public void printName(){
		System.out.println("this is "+name);
	}
}

输出:
this is my Thread Thread-0
this is jkf


这是最简单的方法,创建一个线程,通过重写run方法,可以实现一些自定义的操作。
通过查看Thread类的run方法,
public void run() {
  if (target != null) {
       target.run();
   }
}
还可以通过设置target对象,调用target的run方法,而private Runnable target; 是一个Runnable对象,而Thread提供这样的构造函数。这就是创建多线程的第二种方式:实现Runnable接口

2 实现Runnable接口

package com.thread;

public class ThreadCreateRunnable {
	public static void main(String[] args) {
		Printer printer = new Printer(new User("jkf"));
		new Thread(printer).start();
	}
}

class Printer implements Runnable{
	private User u;
	public Printer(User u) {
		this.u=u;
	}
	public void run() {
		u.printName();		
	}
}
输出内容:
this is jkf

通过提取print方法,通过Printer实现Runnable接口,实现线程的创建。

两者的区别:

1 一个是通过继承Thread类实现,一个通过实现Runnable接口实现,建议通过实现Runnable接口来创建线程,因为java类支持多实现,单继承,如果继承Thread类,那么就不能继承其他类了。

在Thread中,还有一个run(),通过上述的两个例子,发现我们启动线程都是通过start方法,而线程最后调用的仍然是run方法,那么为什么直接调用run方法,即t.run()。这涉及到jvm的底层,如果要创建一个线程那么就必须通过start方法,这才是真正的生成一个新的线程。
实例:

public static void main(String[] args) {
	Thread t = new MyThread(new User("jkf"));
	t.run();
}
//把方法一种的t.start()修改为t.run(),输出如下:
this is my Thread main
this is jkf

t.start()的输出如下:
this is my Thread Thread-0
this is jkf

    两者的主要区别就是this is my Thread Thread-0中Thread的名称。
其中main表示的是主线程,即main线程,因为启动main方法,那么就是一个进程,一个进程对应一个线程,因此main线程就是最初的线程,而Thread-0是通过main创建的新线程。因此可以发现:t.start()创建了Thread-0,而t.run()却仍然是主线程在调用,因此并不会创建新线程。
    因此启动一个线程必须通过.start方法。

技巧

当我们创建一个线程时,最好给该线程使用一个有含义的名称,这样排查起来方便,看到线程名称就知道是使用于什么业务。

Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {

            }
        },"com.csdn.trade.createOrder");

小思考

前面说到,进程可以有多个线程,多个线程共用进程的内存等内容,思考:1个进程创建了3个线程,如果有一个线程内存溢出了,请问另外两个线程怎么样了?

-----main方法执行上述方法前,请配置main方法的jvm参数,防止电脑跟着一起挂了
vm option:
-Xms1m -Xmx1m -XX:+HeapDumpOnOutOfMemoryError
同时为了好查看,最好把输出内容输出到文件中,这样通过文件进行查看

public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<String[]> list = new ArrayList<>();
                while(true){
                    System.out.println("this is thread"+Thread.currentThread().getName()+",我要内存512");
                    String[] arr = new String[512];
                    list.add(arr);
                }

            }
        },"thread-512").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<String[]> list = new ArrayList<>();
                while(true){
                    System.out.println("this is thread"+Thread.currentThread().getName()+",我要内存2048");
                    String[] arr = new String[2048];
                    list.add(arr);
                }
            }
        },"thread-2048").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<String[]> list = new ArrayList<>();
                while(true){
                    System.out.println("this is thread"+Thread.currentThread().getName()+",我要内存1024");
                    String[] arr = new String[1024];
                    list.add(arr);
                }
            }
        },"thread-1024").start();
    }

--- 截取一部分输出内容

this is threadthread-1024,我要内存1024
this is threadthread-512,我要内存512
this is threadthread-1024,我要内存1024
this is threadthread-512,我要内存512
this is threadthread-512,我要内存512
this is threadthread-1024,我要内存1024
this is threadthread-512,我要内存512
this is threadthread-1024,我要内存1024
Exception in thread "thread-512" java.lang.OutOfMemoryError: Java heap space
	at cn.gov.zcy.vaccine.plan.dto.VaccinePlanProductsDto$1.run(VaccinePlanProductsDto.java:57)
	at java.lang.Thread.run(Thread.java:745)
this is threadthread-1024,我要内存1024
this is threadthread-1024,我要内存1024
this is threadthread-1024,我要内存1024
this is threadthread-1024,我

通过输出内容,可以看到两个线程都在运行,后来512的线程内存溢出,但是1024的线程继续执行

猜你喜欢

转载自blog.csdn.net/u010652576/article/details/78569325