举个小栗子,重新理解一下synchronized,volatile,wait(),notify(),join()

   日期:2020-09-05     浏览:97    评论:0    
核心提示:直接步入正题:1、若有一个方法需要实现多线程情况下一个一个访问,则可使用synchronized关键字来实现。2、若有一个工作是需要用两个或多个线程来共同协作完成,并且必须是完成某个动作之后才能执行下一个动作,则可使用 wait()和 notify() 结合来操作,也可使用volatile关键字来实现 。举个栗子:public class TestWait { String name = QQQ;//随意 volat...

 

直接步入正题:

1、若有一个方法需要实现多线程情况下一个一个访问,则可使用synchronized关键字来实现。

2、若有一个工作是需要用两个或多个线程来共同协作完成,并且必须是完成某个动作之后才能执行下一个动作,则可使用 wait() 和 notify() 结合来操作,也可使用volatile关键字来实现 ,也可以使用join()来实现。

举个栗子:


public class TestWait {

	String name = "QQQ";//随意

	volatile boolean flag = false;// volatile 关键字使flag线程之间可见
	
	
	public synchronized void eat() {
		System.out.println("当前线程ID:" + Thread.currentThread().getId() + ",在吃饭,等会吧");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("当前线程ID:" + Thread.currentThread().getId() + ",吃完了,下一位");
		System.out.println("===============================================\n");
	}

	
	public void downAndShow() {
		// 开启一个线程专门下载图片
		new Thread(new Runnable() {
			public void run() {
				downLoad();
			}
		}).start();

		// 开启一个线程专门显示图片
		new Thread(new Runnable() {
			public void run() {
				show();
			}
		}).start();
	}

	public void downLoad() {
		System.out.println("开始下载图片");
		for (int i = 0; i < 101; i += 10) {
			System.out.println("down" + i + "%");
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		synchronized (name) {
			name.notify();
		}
		System.out.println("图片下载成功");
	}

	public void show() {
		synchronized (name) {
			try {
				name.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("展示图片");
		}
	}
	
	
	
	public void volatileDownAndShow() {
		
		// 开启一个线程专门下载图片
		new Thread(new Runnable() {
			public void run() {
				volatileDownLoad();
			}
		}).start();
		
		// 开启一个线程专门显示图片
		new Thread(new Runnable() {
			public void run() {
				volatileShow();
			}
		}).start();
	}
	
	public void volatileDownLoad() {
		System.out.println("开始下载图片");
		for (int i = 0; i < 101; i += 10) {
			System.out.println("down" + i + "%");
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		flag = true;//设置flag为true,表示我已经把图片下载好了,剩下的交给你了兄弟
		System.out.println("图片下载成功");
	}
	
	public void volatileShow() {
		while (true) {//死循环,模拟自旋锁
			if(flag){//因为flag 为volatile 所以在线程之间可见,线程1改变后,线程2也会随之改变
				System.out.println("展示图片");
				break;
			}
		}
	}

    
	public void JoinDownAndShow() throws InterruptedException {
		
		// 开启一个线程专门下载图片
		Thread thread1 = new Thread(new Runnable() {
			public void run() {
				JoinDownLoad();
			}
		});
		
		// 开启一个线程专门显示图片
		Thread thread2 = new Thread(new Runnable() {
			public void run() {
				JoinShow();
			}
		});
		
		thread1.start();
		thread1.join();// thread1调用join()方法,等到thread1执行完毕之后才执行下面操作
		thread2.start();
	}
	
	public void JoinDownLoad() {
		System.out.println("join() 方式 开始下载图片");
		for (int i = 0; i < 101; i += 10) {
			System.out.println("down" + i + "%");
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("图片下载成功");
	}
	
	public void JoinShow() {
		System.out.println("展示图片");
	}
}

编写测试类:

public class Test {

	public static void main(String[] args) {
		final TestWait tt = new TestWait();
		//开始10个线程来模拟排队吃饭
//		for(int i=0;i<10;i++){
//			new Thread(new Runnable() {
//				public void run() {
//					tt.eat();
//				}
//			}).start();;
//		}
		
//		tt.downAndShow();
//		tt.volatileDownAndShow();
		tt.JoinDownAndShow();
	}
}

结果展示:

1、排队吃饭示例:

2、wait() 和 notify() 实现下载图片后展示:

3、volatile方式实现下载图片后展示:

就酱。共勉

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服