线程、锁

package test;

class Test
{
	public static void main(String args[])
	{
		FirstThread first = new FirstThread();
		SecomdThread second = new SecomdThread();
		//java.lang.Thread.Thread(Runnable target)方法
		Thread oneThread = new Thread(first);
		Thread twoThread = new Thread(second);
		oneThread.start();
		twoThread.start();
		
		try {
			System.out.println("waiting for firstThread end");
			//使用thread.join()使得主线程挂起,直到oneThread执行完毕,才会执行
			oneThread.join();
			System.out.println("wakeup secondThread");
			second.suspend();
		} catch (InterruptedException e) {
			// TODO: handle exception
		}
	}
	
}

//通过实现接口Runnable,实现方法run(),来创建线程
class FirstThread implements Runnable
{
	public void run() {
/*
 * void java.lang.Thread.sleep(long millis) throws InterruptedException
 * sleep()是要进行异常处理的
*/
		try {
			System.out.println("first thread is running");
			for (int i = 0; i < 10; i++) {
				System.out.println("\t first"+i);
				Thread.sleep(1000);
				
			}
			
			System.out.println("first thread ended");
		} catch (InterruptedException e) {
			// TODO: handle exception
		}
		
	}

}

//通过实现接口Runnable,实现方法run(),来创建线程
class SecomdThread implements Runnable
{
	public void run() {
		try {
			System.out.println("second thread is running");
			for (int i = 0; i < 10; i++) {
				if (i != 4) {
					System.out.println("\t second"+i);
					Thread.sleep(1000);
				}
				else {
					/*
					 * synchronized,修饰符,加锁
					 * 这里主要是实现自身挂起
					*/
				synchronized (this) {
						wait();
					}
				}
			}
			
			System.out.println("second thread ended");
		} catch (InterruptedException e) {
			// TODO: handle exception
		}
		
	}
	
	void suspend()
	{
		/*
		 * synchronized,修饰符,加锁
		 * 这里主要是实现自身解挂
		*/
		synchronized (this) {
			notify();
		}
	}

}

2、代码二,同步、互斥问题

package test;

class Test
{
	public static void main(String args[])
	{
		FirstThread first = new FirstThread();
		SecomdThread second = new SecomdThread();
		ThirdThread third = new ThirdThread();
		//java.lang.Thread.Thread(Runnable target)方法
		Thread oneThread = new Thread(first);
		Thread twoThread = new Thread(second);
		Thread thirdThread = new Thread(third);
		oneThread.start();
		twoThread.start();
		thirdThread.start();
		
		try {
			System.out.println("waiting for firstThread end");
			//使用thread.join()使得主线程挂起,直到oneThread执行完毕,才会执行
			oneThread.join();
			System.out.println("wakeup Thread");
			second.suspend();
		} catch (InterruptedException e) {
			// TODO: handle exception
		}
	}
	
}

//通过实现接口Runnable,实现方法run(),来创建线程
class FirstThread implements Runnable
{
	public void run() {
/*
 * void java.lang.Thread.sleep(long millis) throws InterruptedException
 * sleep()是要进行异常处理的
*/
		try {
			System.out.println("first thread is running");
			for (int i = 0; i < 10; i++) {
				System.out.println("\t first"+i);
				Thread.sleep(1000);
				
			}
			
			System.out.println("first thread ended");
		} catch (InterruptedException e) {
			// TODO: handle exception
		}
		
	}

}

//通过实现接口Runnable,实现方法run(),来创建线程
class SecomdThread implements Runnable
{
	//做同步控制用
	public static Object obj = new Object();
	public void run() {
		try {
			System.out.println("second thread is running");
			for (int i = 0; i < 10; i++) {
				if (i != 4) {
					System.out.println("\t second"+i);
					Thread.sleep(1000);
				}
				else {
					/*
					 * synchronized,修饰符,加锁,标示这里是临界区,需要锁才能访问临界区;
					 * 同一个锁被占有,要访问临界区的线程会进入该锁对象的就绪列表
					 * 而wait会将占有的锁(这里是对象锁)释放,该线程进入锁对象的阻塞队列。
					 * 就绪列表的线程得到锁后,将会继续在临界区执行
					 * notify将wait的线程唤醒,进入阻塞队列,并允许它得到锁
					*/
				synchronized (obj) {
					System.out.println("second");
					obj.wait();
					System.out.println("second_next");
					}
				}
			}
			
			System.out.println("second thread ended");
		} catch (InterruptedException e) {
			// TODO: handle exception
		}
		
	}
	
	void suspend()
	{
		/*
		 * synchronized,修饰符,加锁
		 * 这里主要是实现自身解挂
		*/
		synchronized (obj) {
			obj.notify();
		}
	}

}

//通过实现接口Runnable,实现方法run(),来创建线程
class ThirdThread implements Runnable
{
	public void run() {
		try {
			System.out.println("third thread is running");
			for (int i = 0; i < 10; i++) {
				if (i != 4) {
					System.out.println("\t third"+i);
					Thread.sleep(1000);
				}
				else {

				synchronized (SecomdThread.obj) {
					System.out.println("third");
					SecomdThread.obj.wait();
					System.out.println("third_next");
					}
				}
			}
			
			System.out.println("third thread ended");
		} catch (InterruptedException e) {
			// TODO: handle exception
		}
		
	}
	
	void suspend()
	{
		synchronized (SecomdThread.obj) {
			SecomdThread.obj.notify();
		}
	}

}

运行结果之一:

first thread is running
first0
waiting for firstThread end
second thread is running
second0
third thread is running
third0
third1
second1
first1
third2
first2
second2
first3
second3
third3
third
first4
second
first5
first6
first7
first8
first9
first thread ended
wakeup Thread
third_next
third5
third6
third7
third8
third9
third thread ended

分析:

1、third先得到obj对象锁,打印third,之后调用wait,释放锁,同时阻塞线程;

2、由于obj锁已被释放,从而second可以获得锁,进而访问临界区,打印second,之后之后调用wait,释放锁,同时阻塞线程;

3、即third线程、second线程都进入了阻塞队列,之后调用notify,唤醒一个线程,队列是先进先出,即third线程会出队列,进而获得obj对象锁。(虽然是使用代码

second.suspend();

唤醒线程,但注意它针对的是obj这个阻塞队列

4、third线程会继续执行临界区,执行完毕后,自然就要释放锁了。但是,second一直在阻塞队列,无人唤醒,无法获得锁,从而导致它一直阻塞,不会继续执行,也就没有打印剩余的信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值