java中的并发:线程的基本使用

目录
  1.生命周期
  2.常用方法
  3.守护线程
1.生命周期

  1)初始状态    此时线程处于JVM的进程中,只是创建了一个线程对象,并没有开始运行.(new())
  2)就绪状态
    此时线程进入可运行状态,等待CPU调度.(start())
  3)运行状态
    拥有CPU的执行权,并且开始运行线程.(run())
  4)阻塞状态
    线程在等待IO或者调入了sleep()或join()等方法会导致线程进入阻塞状态,从阻塞状态出来的线程不一定马上回到运行状态,而是回到可运行状态等待CPU的再次调度.(blocked)
  5)等待队列状态
    一个线程调用一个对象的wait()方法会放弃该对象的锁并进入等待队列状态,只有当另一线程调用临界资源的notify()或者notifyAll()才会将等待队列中的线程释放,进入锁池状态.(waiting)
  6)锁池状态
    每个对象都有互斥锁标记,如果一个线程想访问一个对象,而该对象的锁标记已被另一线程占用,则该线程进入锁池状态.从锁池状态出来的线程回到可运行状态,等待CPU调度.(locked)
  7)终止状态
    一个线程运行结束后称为终止状态,也叫死亡状态一个进程只有所有的线程退出后才能终止.(dead)

 

 

2.常用方法

  线程操作
    currentThread()   返回对当前正在执行的线程对象
    run()    线程体内执行的代码应该都放在run方法里,用户不应该直接调用run()方法
    start()    使该线程开始执行并调用该线程的run方法
    yield()    暂停当前正在执行的线程对象,并执行其他线程
    sleep()    在指定的毫秒数内让当前正在执行的线程休眠
    join()    等待该线程终止
    interrupt()   中断线程
  线程测试
    isAlive()   测试线程是否处于活动状态
    isInterrupted()   测试线程是否已经中断
    isDaemon()   测试该线程是否为守护线程
  线程属性
    setName()   改变该线程的名称
    getName()   返回该线程的名称
    setPriority()   更改线程的优先级
    getPriority()   返回线程的优先级
    setDaemon()   将该线程标记为守护线程或用户线程

  1)每一个java程序都有一个默认的主线程,即main()函数.

				public class ThreadDemo {
					public static void main(String[] args) {
						Thread thr = new Thread(new MyThread());
						thr.start();
						int j = 0;
						while (j++ < 10) {
							System.out.println(Thread.currentThread().getName() + "..." + j);
							try {
								Thread.sleep(1000);
							} catch (InterruptedException e) {
							}
						}
					}
				}

				class MyThread implements Runnable {
					@Override
					public void run() {
						int i = 0;
						while (i++ < 10) {
							System.out.println(Thread.currentThread().getName() + "..." + i);
							try {
								Thread.sleep(1000);
							} catch (InterruptedException e) {
							}
						}
					}
				}

运行结果:main线程和Thread-0线程不规则交替执行,各自每隔1s输出直到结束.

  2)调用join方法会在当前线程内等待某一线程终止,内部调用了Object的wait()方法.例:

				public class ThreadDemo {
					public static void main(String[] args) {
						Thread thr = new Thread(new MyThread());
						thr.start();
						try {
							thr.join();
						} catch (InterruptedException e) {
						}
						int j = 0;
						while (j++ < 100) {
							System.out.println(Thread.currentThread().getName() + "..." + j);
						}
					}
				}

				class MyThread implements Runnable {
					@Override
					public void run() {
						int i = 0;
						while (i++ < 100) {
							System.out.println(Thread.currentThread().getName() + "..." + i);
						}
					}
				}

运行结果:Thread-0线程全部输出完毕,main线程才继续执行.

  3)调用interrupt()方法可以使得处于阻塞状态的线程抛出一个异常,不会中断正在运行的程序.例:

				public class ThreadDemo {
					public static void main(String[] args) {
						Thread thr = new Thread(new MyThread());
						thr.start();
						try {
							Thread.sleep(1000);
						} catch (InterruptedException e) {
						}
						thr.interrupt();
					}
				}

				class MyThread implements Runnable {
					@Override
					public void run() {
						int i = 0;
						while (i++ < Integer.MAX_VALUE) {
							System.out.println(Thread.currentThread().getName() + "..." + i);
						}
					}
				}

  运行结果:thr会一直运行.
  但是,调用interrupt()会将中断标志位(isInterrupted())置为true,因此可以通过判断标志位来中断线程:

				class MyThread implements Runnable {
					@Override
					public void run() {
						int i = 0;
						while (!(Thread.currentThread().isInterrupted()) && i++ < Integer.MAX_VALUE) {
							System.out.println(Thread.currentThread().getName() + "..." + i);
						}
					}
				}

运行结果:thr运行一段时间后停止.
  一般情况下不建议通过这种方式来中断线程,一般会在MyThread类中增加一个属性isStop来标志是否结束while循环,然后再在while循环中判断isStop的值.

3.守护线程

  通过setDaemon(true)方法可以设置一个线程为守护线程,守护线程优先级比较低,随着主线程运行完毕自动结束.在JVM中,像垃圾收集器线程就是守护线程.例:

				public class Test {
					@Override
					public void finalize() {
						System.out.println(Thread.currentThread().getName() + "收垃圾喽~");
					}

					public static void main(String[] args) {
						new Test();
						System.gc();
						System.out.println("主线程Over~");
					}
				}

运行结果:
    主线程Over~
    Finalizer收垃圾喽~

猜你喜欢

转载自xiao1zhao2.iteye.com/blog/2230999