java多线程与单线程相比,最大的优点是在多任务的情况下多线程比单线耗时短,可以并发进行
有时候对于单核计算机,我们也觉得很多任务是并发进行的,主要是因为我们的单核cpu对时间进行分片,对
每个任务都分配了时间片。比如给qq分配3ms给腾讯视频分了3ms等等,虽然我们看任务是并行的,实则是
分时运行的。而多核cpu则可以真正并发,这就是多核cpu执行的优势。
下面有一个简单的程序是对java单线程多线程的比较
public class ConcurrencyTest {
private static final long count = 1000000001;
public static void main(String args[]) throws InterruptedException
{
concurrency();
seria();
}
//多线程情况下
private static void concurrency() throws InterruptedException
{ //获取当前系统时间
long start = System.currentTimeMillis();
Thread thread = new Thread(new Runnable()
{
@Override
public void run()
{
long a = 0;
for(int i = 0;i < count;i++)
{
a+=5;
}
}
});
thread.start();
long b = 0;
for(int i = 0;i
package java_Join;
public class ConcurrencyTest {
private static final long count = 1000000001;
public static void main(String args[]) throws InterruptedException
{
concurrency();
seria();
}
//多线程情况下
private static void concurrency() throws InterruptedException
{ //获取当前系统时间
long start = System.currentTimeMillis();
Thread thread = new Thread(new Runnable()
{
@Override
public void run()
{
long a = 0;
for(int i = 0;i < count;i++)
{
a+=5;
}
}
});
thread.start();
long b = 0;
for(int i = 0;i
其中对join的理解其中有参照
个人简单理解是将该线程加入到主线程,主线程要等待其结束,如果该线程没有结束主线程不能结束
比如,你想喝茶,你要烧水,洗茶具,泡茶,喝茶。烧水与洗茶具没什么关联,你可以分开进行,但
是你喝茶的话必须得每件事都完成,所以烧水这种费时的动作就交由一个线程去做,等洗好茶具等烧
水线程完成,就可以泡茶喝茶了。
join是Thread类的一个方法,启动线程后直接调用例如
Thread t = new AThread(); t.start(); t.join();
在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,这个时候就要用到join()方法了。
三、join方法的作用
join
public final void join() throws InterruptedException Waits for this thread to die.
Throws: InterruptedException - if any thread has interrupted the current thread.
The interrupted status of the current thread is cleared when this exception is thrown.
即join()的作用是:“等待该线程终止”,这里需要理解的就是该线程是指的主线程等待子线程的终止。也就是在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行。四、从源码看join()方法
join()的JDK源码
/**
* Waits for this thread to die.
* An invocation of this method behaves in exactly the same
* way as the invocation
*
*
* {@linkplain #join(long) join}{@code (0)}
*
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* interrupted status of the current thread is
* cleared when this exception is thrown.
*/
public final void join() throws InterruptedException {
join(0);
}
/**
* Waits at most {@code millis} milliseconds for this thread to
* die. A timeout of {@code 0} means to wait forever.
*
* This implementation uses a loop of {@code this.wait} calls
* conditioned on {@code this.isAlive}. As a thread terminates the
* {@code this.notifyAll} method is invoked. It is recommended that
* applications not use {@code wait}, {@code notify}, or
* {@code notifyAll} on {@code Thread} instances.
*
* @param millis
* the time to wait in milliseconds
*
* @throws IllegalArgumentException
* if the value of {@code millis} is negative
*
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* interrupted status of the current thread is
* cleared when this exception is thrown.
*/
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;
}
}
}
写一个简单的例子来看一下join()的用法:
主要包含三个类
1.TestDemo 类
1.AThread 类
2.BThread类
TestDemo 类是主类main线程,主类里面加入了AThread 类的线程,AThread 类又加入了BThread类
class AThread extends Thread {
BThread bt;
public AThread(BThread bt) {
super("[AThread] Thread");
this.bt = bt;
}
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start.");
try {
// 这里加入了bt线程
bt.join();
System.out.println(threadName + " end.");
} catch (Exception e) {
System.out.println("Exception from " + threadName + ".run");
}
}
}
class BThread extends Thread {
public BThread() {
super("[BThread] Thread");
};
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start.");
try {
for (int i = 0; i < 5; i++) {
System.out.println(threadName + " loop at " + i);
Thread.sleep(1000);
}
System.out.println(threadName + " end.");
} catch (Exception e) {
System.out.println("Exception from " + threadName + ".run");
}
}
}
public class TestDemo {
public static void main(String[] args) {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start."+"时间 :"+System.currentTimeMillis());
BThread bt = new BThread();
AThread at = new AThread(bt);
try {
bt.start();
Thread.sleep(2000);
at.start();
at.join();
} catch (Exception e) {
System.out.println("Exception from main");
}
System.out.println(threadName + " end!"+"时间 :"+System.currentTimeMillis());
}
}
可以看得到进程运行变化。
main start.时间 :1497456321225
//主线程起动,因为调用了at.join(),要等到at结束了,此线程才能向下执行
主线程睡眠2000ms
[BThread] Thread start.时间 :1497456321226[BThread] Thread loop at 0时间 :1497456321226
//睡眠1000ms
[BThread] Thread loop at 1时间 :1497456322230
//睡眠1000ms
[BThread] Thread loop at 2时间 :1497456323231
[AThread] Thread start.
//A程起动,因为调用了bt.join(),要等到bt结束了,此线程才能向下执行
[BThread] Thread loop at 3时间 :1497456324236
[BThread] Thread loop at 4时间 :1497456325241
[BThread] Thread end.时间 :1497456326245
[AThread] Thread end.
// 线程AThread在bt.join();阻塞处开始启动,向下继续执行的结果
main end!
//线程AThread结束,此线程在at.join();阻塞处开始启动,向下继续执行的结果。
修改主方法类:
public class TestDemo {
public static void main(String[] args) {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start."+"时间 :"+System.currentTimeMillis());
BThread bt = new BThread();
AThread at = new AThread(bt);
try {
bt.start();
Thread.sleep(2000);
at.start();
//at.join(); //在此处注释掉对join()的调用
} catch (Exception e) {
System.out.println("Exception from main");
}
System.out.println(threadName + " end!"+"时间 :"+System.currentTimeMillis());
}
}
结果为
main start.时间 :1497457025126
// 主线程起动,因为Thread.sleep(2000),主线程没有马上结束;
[BThread] Thread start.时间 :1497457025128
//线程BThread起动
[BThread] Thread loop at 0时间 :1497457025128
[BThread] Thread loop at 1时间 :1497457026128
main end!时间 :1497457027128
//2000ms后主线程结束,留下AThread,与BThread
[AThread] Thread start.
//2000ms线程at启动,因为调用了bt.join(),等到bt结束了,此线程才向下执行。
[BThread] Thread loop at 2时间 :1497457027128
[BThread] Thread loop at 3时间 :1497457028130
[BThread] Thread loop at 4时间 :1497457029131
[BThread] Thread end.时间 :1497457030137
//线程BThread结束了,线程AThread在bt.join();阻塞处开始启动,向下继续执行的结果
[AThread] Thread end.
参考文章:http://www.open-open.com/lib/view/open1371741636171.html