​​Java多线程创建与运行​​理了一下线程的创建和运行,可以看到线程最终都是通过​​new一个Thread实例​​​,然后调用​​start()方法​​来运行的。

但是我们可以看到,一个线程的所要执行的任务方法体都是重写到​​run()​​​方法里面的。
但是这里是调用的start()方法来运行线程的,这说明start()方法做了一系列工作来新建一个线程运行run()方法里面的行为,而不是从当前这个main()函数的线程去运行他。

​​线程的属性​​ 根据线程的属性,我们可以自己设定线程的名称。

Runnable runnable = ()->{
System.out.println(Thread.currentThread().getName());
};

Thread threadName = new Thread(runnable);
// 设置要创建的线程名称
threadName.setName("codeXT");
threadName.start();
//如下方式并不会创建新线程执行run()方法
threadName.run();

Thread.Start()方法运行多线程_上下文切换

start()方法由​​synchronized​​修饰,synchronized修饰的资源相当于临界资源,一个线程进去之后,其他线程调用会被阻塞挂起。而java线程和操作系统线程对应,会导致用户态到内核态的切换来执行阻塞,会引起上下文切换,时间耗费比较大。在退出synchronized修饰的资源时,会将共享变量的修改刷新到主内存,来保证内存可见性。

public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();

/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);

boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}

调用start()时,会判断threadStatus != 0,threadStatus是记录线程的状态,初始默认为0,当线程启动后,threadStatus的值会发生改变,当第二次调用start()时,就会抛出异常。start()方法只会被执行一次,也就是只能开启一个线程。

if (threadStatus != 0)
throw new IllegalThreadStateException();

​threadStatus​​​ 由​​volatile​​​修饰,确保了​​内存可见性​​问题,就是说这个变量的值对于其他线程也是立马可见的最新值,会将更新的变量更新到主内存,确保了内存可见性。但是volatile修饰不保证原子性,是非阻塞的。

private volatile int threadStatus = 0;