天天看点

Java多线程设计

操作系统在运行一个程序时候,会首先创建一个进程。如果启动一个java程序就会创建一个java进程。现代操作系统的调度的最小单位是线程,也叫轻量级进程。一个进程中可以创建多个线程。香河县线程都拥有自己各自的计数器,堆栈,和局部变量等属性,并且能够共享访问内存变量。处理器在这些线程上高速切换,让你我感觉到是在并行执行。

在java运行时候不只是启动一个main线程运行,请看一下下边的例子

运行结果

为什么要用多线程,也就是一个字“快”,天下程序唯快不破

1.可以利用多个处理器的核心

2.更快的响应时间:

有时候我么会写一些比较复杂的业务代码。比如:一笔订单的创建,包括插入订单数据,生成订单快照,发送邮件通知卖家,记录货品销售数量等,用户从单击订购按钮开始,就要等待这些操作全部完成看到订购成功的结果,但是这么多的业务操作如何能快速的完成就是用多线程处理,缩短了相应的时间,提升了用户的体验。

3.更好的编程模型

要研究多线程我们先要知道多线程的监控如何做。大家都知道多线程的模块在普通没有经验的程序员来说就不知到哪里有问题。所以我们这里先要学会如何利用工具来看看运行的情况。

先上一段代码:

/**
 * java线程在8个状态之间变切
 * New,Runnable,Running,Waiting,Time_Waiting,Ready,Terminated,blocked
 *
 * @author Janle
 *
 */
public class Test {
	public static void main(String[] args) {
		new Thread(new TimeWaiting(), "TimeWaitingThread").start();
		new Thread(new Waiting(), "WaitingThread").start();
		new Thread(new Blocked(),"BlockedThread-1").start();
		new Thread(new Blocked(),"BlockedThread-2").start();
	}

	// 该线程不断地进行睡眠
	static class TimeWaiting implements Runnable {
		@Override
		public void run() {
			while (true) {
				SleepUtils.second(100);
			}
		}
	}

	// 该线程在Waiting实例上等待
	static class Waiting implements Runnable {
		@Override
		public void run() {
			while (true) {
				synchronized (Waiting.class) {
					try {
						Waiting.class.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	// 该线程在Blocked实例上加锁后不会释放该锁
	static class Blocked implements Runnable {
		@Override
		public void run() {
			synchronized (Blocked.class) {
				while (true) {
					SleepUtils.second(100);
				}
			}
		}

	}
}

class SleepUtils {
	public static final void second(long seconds) {
		try {
			TimeUnit.SECONDS.sleep(seconds);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
           

这里我们jps一下找到对应的pid。

10272 Jps
11816 Test
14600
           

使用jstack pid来看看jstack 11816

//销毁的jvm处于运行状态
"DestroyJavaVM" #14 prio=5 os_prio=0 tid=0x000000000279a000 nid=0x243c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
//BlockedThread-2线程阻塞在获取的Blocked.class示例的锁上
"BlockedThread-2" #13 prio=5 os_prio=0 tid=0x00000000188a1000 nid=0x3100 waiting for monitor entry [0x000000001963f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.lenovo.lenjoy.Test$Blocked.run(Test.java:52)
        - waiting to lock <0x00000000d5f5b238> (a java.lang.Class for com.lenovo.lenjoy.Test$Blocked)
        at java.lang.Thread.run(Thread.java:745)
//BlockedThread-1获得到了Blocked.class的锁
"BlockedThread-1" #12 prio=5 os_prio=0 tid=0x00000000188a0800 nid=0x16e0 waiting on condition [0x000000001953f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at java.lang.Thread.sleep(Thread.java:340)
        at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
        at com.lenovo.lenjoy.SleepUtils.second(Test.java:63)
        at com.lenovo.lenjoy.Test$Blocked.run(Test.java:52)
        - locked <0x00000000d5f5b238> (a java.lang.Class for com.lenovo.lenjoy.Test$Blocked)
        at java.lang.Thread.run(Thread.java:745)
//WaitingThread线程在Waiting实例上等待
"WaitingThread" #11 prio=5 os_prio=0 tid=0x0000000018872800 nid=0x254c in Object.wait() [0x000000001943e000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000d5f54058> (a java.lang.Class for com.lenovo.lenjoy.Test$Waiting)
        at java.lang.Object.wait(Object.java:502)
        at com.lenovo.lenjoy.Test$Waiting.run(Test.java:37)
        - locked <0x00000000d5f54058> (a java.lang.Class for com.lenovo.lenjoy.Test$Waiting)
        at java.lang.Thread.run(Thread.java:745)
//TimeWaitingThread线程处理超时等待
"TimeWaitingThread" #10 prio=5 os_prio=0 tid=0x0000000018897800 nid=0x28a4 waiting on condition [0x000000001933f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at java.lang.Thread.sleep(Thread.java:340)
        at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
        at com.lenovo.lenjoy.SleepUtils.second(Test.java:63)
        at com.lenovo.lenjoy.Test$TimeWaiting.run(Test.java:25)
        at java.lang.Thread.run(Thread.java:745)

"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x000000001744e800 nid=0x24d0 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x0000000017421800 nid=0x4f4 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x000000001741e800 nid=0x203c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x000000001741c000 nid=0x36d0 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000000001741b000 nid=0x7a4 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001741a000 nid=0x3140 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000002888000 nid=0x26dc in Object.wait() [0x000000001873f000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000d6090180> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:142)
        - locked <0x00000000d6090180> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:158)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00000000173b8000 nid=0x2df4 in Object.wait() [0x000000001863f000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000d6088210> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157)
        - locked <0x00000000d6088210> (a java.lang.ref.Reference$Lock)

"VM Thread" os_prio=2 tid=0x00000000173b6800 nid=0x3684 runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00000000027b0000 nid=0x2cc4 runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00000000027b1800 nid=0xf00 runnable

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00000000027b3800 nid=0x9d0 runnable

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00000000027b5000 nid=0x2918 runnable

"VM Periodic Task Thread" os_prio=2 tid=0x00000000187de800 nid=0x1c40 waiting on condition

JNI global references: 7