
在JAVA中,谈到并发问题肯定是谈到多线程相关。可以说这两个之间有着一定的关系。在这里就为大家简单的说下多线程的基础,之后的文章中会继续讲解多线程相关。
什么是线程
线程是进程内的执行单元。一个进程中含有若干个线程,线程可以看做粒度更小的任务执行单元。进程之间切换,消耗的资源是很大的。通过线程去处理会很好的节省相关资源。
线程状态转化

这上面是针对于线程的状态转化一个简单描述。这上面可以看到blocked的之间的状态只有一条线来回。这块的话关乎到
sychronized的底层实现原理,大家可以自行了解下。这里面我就省略了一个Running的一个状态。Running的状态在可运行状态(Runnable)之后。
线程实现几种方式
- 继承Thread类
- 实现Runnable接口
- 实现Callable接口
上面是是实现线程的三种方式。在调用线程时候,调用的是其
start()方法,而不是调用的run()方法。其中第三种实现方式结合Future可以获取到线程的返回值(同时,在线程池里面运行多线程的话,使用exec.execute()是拿不到线程执行的返回值,使用exec.submit()可以通过上面的Future取得线程执行的返回值)。
线程方法
1.stop(),这个方法使得当前所运行的线程停止,释放所有的monitor。但是使用这个方法会导致多线程的数据不一致性(假设两个线程执行中去停止,再次操作的时候,线程2有可能抢到原本线程1执行的步骤上)。
@Deprecated //提示过期方法
public final void stop() {
//获取SecurityManager进行校验
SecurityManager security = System.getSecurityManager();
if (security != null) {
checkAccess();
if (this != Thread.currentThread()) {
security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
}
}
if (threadStatus != 0) {
// 如果线程被挂起,则唤醒线程;否则不执行任何操作
resume();
}
// 调用系统方法去停止线程
stop0(new ThreadDeath());
}
2.interrupt(),这个方法会设置线程中断状态。是一个比较合理使用的一个方法。
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {//加锁控制
Interruptible b = blocker;
if (b != null) {
interrupt0(); // 设置中断位
b.interrupt(this);
return;
}
}
interrupt0();
}
3.interrupted()判断当前线程是否被中断,并且清除当前线程中断状态。
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
4.sleep()方法是让线程等待的。在大多数线程等待的方法中都会抛出InterruptedException异常。同时该方法不会释放锁以及所占用的资源。同时它会清除中断标志,所以在catch中再对该线程设置下中断标志。
public static native void sleep(long millis) throws InterruptedException;
5.suspend()方法是让当前线程挂起,不会释放锁。
@Deprecated
public final void suspend() {
checkAccess();
suspend0();
}
6.resume()方法是让线程继续执行。使用这个的方法就有一个注意点,如果调用这个方法在suspend之前,那么线程就会永久的挂起,这个时候就会永久的占用了资源,可能会导致死锁的发生。
@Deprecated
public final void resume() {
checkAccess();
resume0();
}
7.join()的主要作用就是同步,它可以使得线程之间的并行执行变为串行执行。
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
这里面实际上调用的还是Object中的wait()方法。
这块也是对于当前使用最多的线程操作方法做了一个小的总结,在下一讲中我会谈及到JUC下面的各个锁操作。