线程的基本操作2

Posted zkfly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程的基本操作2相关的知识,希望对你有一定的参考价值。

等待(wait) 和通知(notify)

这两个方法来自Object类, 使用前必须先获得目标的锁.

wait()使用场景必须包含在synchronzied语句中., 当调用后,线程释放锁, 进入object对象的等待队列, 等待notify() .notifyAll()去唤醒.

package threads;

public class WaitAndNotify {
	final static Object ob = new Object();

	public static class T1 extends Thread {
		@Override
		public void run() {
			synchronized (ob) {
				System.out.println(System.currentTimeMillis() + " : " + "T1.start");
				try {
					System.out.println(System.currentTimeMillis() + " : " + "T1.wait");
					ob.wait();//放开锁,停止继续执行下一步
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(System.currentTimeMillis() + " : " + "T1.end");
			}
		}
	}

	public static class T2 extends Thread {
		@Override
		public void run() {
			synchronized (ob) {
				System.out.println(System.currentTimeMillis() + " : " + "T2.start");
				ob.notify();// 提示其他进程去获取锁
				System.out.println(System.currentTimeMillis() + " : " + "T2.end");
				try {
					Thread.sleep(2000);//占用锁没有放开.导致t2end比t1end早两秒
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	public static void main(String[] args) {
		Thread t1 = new T1();
		Thread t2 = new T2();
		t1.start();
		t2.start();
	}
}
1568212250034 : T1.start
1568212250034 : T1.wait
1568212250034 : T2.start
1568212250034 : T2.end  两秒
1568212252034 : T1.end

 等待线程结束join() 和 谦让yield()

有些时候我们需要一个线程依赖其他线程执行完毕才能,才能操作这是使用join()

join 分为2种 , 第一种是无限等待阻塞进程,直到目标线程执行完毕,

                      第二种是有时间限制, 过了时间就不等了,继续执行下一步.

private volatile static int  i = 0;
	
	public static class Nums extends Thread{
		@Override
		public void run() {
			for ( i = 0; i < 10000999; i++);
		}
	}
	
	public static void main(String[] args) throws InterruptedException {
		Nums nums = new Nums(); // 选择目标线程对象, 而不是Thread
		nums.start(); //0
		nums.join(); //10000999
		System.out.println(i);
	}

yiled()是静态方法,使用后 当前线程让出CPU,继续参与CPU的争夺适用于优先级低,害怕占用太多资源的线程.

public class YieldA {
	
	public static class RunCPU extends Thread{
		public  RunCPU(String name) {
			super.setName(name);
		}
		@Override
		public void run() {
			for (int i = 0; i < 50; i++) {
				System.out.println(Thread.currentThread().getName() + ":  " + i);
				if(i == 30) {
					Thread.yield();
					try {
						Thread.sleep(5);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	public static void main(String[] args) {
		RunCPU runCPU = new RunCPU("run111111");
		RunCPU runCPU2 = new RunCPU("run222222");
		runCPU.start(); // 到30让出cpu给runCPU2
		runCPU2.start();// 到30让出cpu给runCPU
	}

}

  

以上是关于线程的基本操作2的主要内容,如果未能解决你的问题,请参考以下文章

线程学习知识点总结

线程-使用CountDownEvent类

newCacheThreadPool()newFixedThreadPool()newScheduledThreadPool()newSingleThreadExecutor()自定义线程池(代码片段

多个用户访问同一段代码

多线程编程

为啥基于锁的程序不能组成正确的线程安全片段?