Java 多线程

1. 线程的优先级

    优先级越高, 线程得到执行的机会就越高

           Thread中.

                 * static int MAX_PRIORITY 
*  最高优先级 10
* static int MIN_PRIORITY
*  子最低优先级 1
* static int NORM_PRIORITY
*  默认优先级 5

2.线程的几个方法

Thread.sleep(Long)

线程睡眠:使线程转到阻塞状态,当阻塞结束后转为就绪状态,等待执行

   Object.wait();

            线程等待:  使当前正在执行的线程等待,直到被调用notify()/notifyAll()时才有可能执行.

注意: 这里的意思是让出cpu,再次执行时 会在源让出点开始继续执行

         

   Thread.yield()

            线程让步: 暂停正在执行的线程,把执行权让给其他优先级更高的线程

注意: 这里让出后有可能再次抢夺cpu继续执行


    Thread.join()

     线程加入:  等待其他线程终止,然后在转为就绪状态等待执行


             线程唤醒  : notify() notifyAll() 唤醒再次对象上监听的或所有的线程

3.sleep和yield区别

sleep使当前线程进入阻塞状态,所以执行sleep的线程在指定时间
 内肯定不会再次执行, yield 只是使当前线程重新回到就绪状态
 所以执行yield的线程有可能进入到就绪状态后马上又被执行
 
 sleep可以执行阻塞时间,yield是不可设定的 yield是线程进入
 就绪状态后, CPU会先检测当前是是否有相同或更高优先级的线程
 如有 则执行, 否则继续执行原来的线程
 
 sleep允许较低优先级线程有运行的机会,单yield不会
 在一个运行系统中, 如果较高优先级线程没有调用sleep
 又没i/o阻塞,那么较低线程只有等到较高线程结束后才能执行

4. join

 

public static void main(String[] args) {
		
		/**
		 * 
		 * 在住线程中其他线程的join方法, 那么主线程会等待子线程运行结束后运行(确切的说转为就绪状态)
		 */
		System.out.println(Thread.currentThread().getName() + " 主线程开始运行.");
		
		Thread t1 = new Thread() {
			@Override
			public void run() {
				for(int i = 0; i < 10; i++) {
					System.out.println("T1 Running!");
				}
			}
		};
		t1.start();
		try {
			t1.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Thread t2 = new Thread() {
			@Override
			public void run() {
				for(int i = 0; i < 10; i++) {
					System.out.println("T2 Running!");
				}
			}
		};
		t2.start();
		try {
			t2.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName() + " 主线程结束.");
		
	}

main 主线程开始运行.
T1 Running!
T1 Running!
T1 Running!
T1 Running!
T1 Running!
T1 Running!
T1 Running!
T1 Running!
T1 Running!
T1 Running!
T2 Running!
T2 Running!
T2 Running!
T2 Running!
T2 Running!
T2 Running!
T2 Running!
T2 Running!
T2 Running!
T2 Running!
main 主线程结束.



5.wait notify  线程间等待与唤醒

刚开始这两个概念比较蒙,他们都必须在synchronized中调用因为是基于对象锁,只有在synchronized中才有对象锁的概念

wait:  当前执行的线程放弃cpu资源 告诉其他监听次对象锁的线程可以执行了, 我等会再这地方继续执行,注意:可以不出synchronized块

notify: 唤醒其他正在等待这个对象锁的线程可以继续执行了,就是告诉他们我搞完了,你们可以搞了  注意: 即使调用了notify,也要等待出了synchronized后,其他线程才可以执行.

        下例子一

两个线程交替打印ABABABABABAB...

public class WaitNOtify_5 implements Runnable {

	private String name;   
    private Object object;   
    public static  int count = 10;
  
    private WaitNOtify_5(String name, Object object) {   
        this.name = name;   
        this.object = object;   
    } 
    
	public static void main(String[] args) {
		Object object = new Object();   
        WaitNOtify_5 pa = new WaitNOtify_5("A", object);   
        WaitNOtify_5 pb = new WaitNOtify_5("B", object);   
           
           
        new Thread(pa).start();
        new Thread(pb).start();
	}


	@Override
	public void run() {
		while(count-- > 0) {
			synchronized(object) {
				System.out.println(name + " - > " + count);
				
				/**
				 * 注意 : notify时, 线程不会立即放弃cpu , 会执行完sychronized块才放弃cpu
				 */
				object.notify();
				
				try {
					/**
					 * 注意: wait时,当前线程放弃cpu,阻塞在这,下次呗notify时,在从这里开始
					 */
					object.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

}
所以: 当A线程进入,获得object锁->打印->notify(虽然第一次没有其他线程引锁的等待,但没关系,没影响)唤醒->等待(卡住)

  B线程进入-> 获得object对象锁(之前A  wait释放的)..........



例子二: 四个线程交替打印 ABCDABCDABCD.......


public class WaitNotify_6 implements Runnable {

	/**
	 * 四个线程交替打印ABCDABCD
	 */

	public static void main(String[] args) throws InterruptedException {

		Object a = new Object();
		Object b = new Object();
		Object c = new Object();
		Object d = new Object();

		WaitNotify_6 ra = new WaitNotify_6("A", d, a);
		WaitNotify_6 rb = new WaitNotify_6("B", a, b);
		WaitNotify_6 rc = new WaitNotify_6("C", b, c);
		WaitNotify_6 rd = new WaitNotify_6("D", c, d);
		
		new Thread(ra).start();
		Thread.sleep(100);
        new Thread(rb).start();
        Thread.sleep(100);
        new Thread(rc).start();
        Thread.sleep(100);
        new Thread(rd).start();
        Thread.sleep(100);

	}

	private String name;
	private Object prev;
	private Object self;

	private WaitNotify_6(String name, Object prev, Object self) {
		this.name = name;
		this.prev = prev;
		this.self = self;
	}

	@Override
	public void run() {
		int count = 5;
		
		while(count -- > 0) {
			/**
			 * 能否打印在于顺序 要前一个打印完成并且释放对应的对象锁 只有获取到前一个对象锁,才能打印
			 */
			synchronized(prev) {
				
				/**
				 * 还要获取当前的锁 才能打印
				 */
				synchronized(self) {
					System.out.println(name);
					
					self.notify();
				}
				
				try {
					prev.wait();
					
					/**
					 * 线程A   获得da锁        释放a锁        等待d锁(卡住)
					 * 线程B   获得ab锁        释放b锁        等待a锁(卡住)
					 * 线程C   获得bc锁        释放c锁        等待b锁(卡住)
					 * 线程D   获得cd锁        释放d锁        等待c锁(卡住)
					 * 线程A   获得da锁        释放a锁        等待d锁(卡住)
					 */
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值