`
sudalyl
  • 浏览: 100483 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

java多线程(2)---睡眠与同步锁

阅读更多

    昨天讲到了如何实现多线程以及多线程的好处,今天我们来看看线程的睡眠sleep(),多线程问题,sleep()是一个静态方法,以毫秒为为单位,我们为什么要使用睡眠呢?那当然是为了我们宝贵的CPU资源能在短时间内为更多的线程服务,而不是在某段时间内一直被某个线程占用。比如某线程在等待一个资源,这个时候我们通常让此线程先阻塞一会,一段时间后继续进入可运行状态,此时如果线程获得了所需的资源则可以继续运行,否则再阻塞,等待资源降临。

    通过阻塞我们可以大大的提高CPU的利用率。下面我们来看一个使用sleep()方法的例子

 

package com.suda.thread;

public class Mythread5 implements Runnable {

	@Override
	public void run() {
		// TODO Auto-generated method stub
		for (int i = 0; i < 10; i++) {
			try {
				Thread.sleep(1000);
				System.out.println(Thread.currentThread().getName() + ",第"
						+ (i + 1) + "次使用");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		Mythread5 mt = new Mythread5();
		Thread thread = new Thread(mt);
		thread.start();

	}

}

 运行上面的代码我们可以看见控制台每隔一秒钟打印出一句话。

 

在进行线程编程时难免涉及到多线程的问题,那么当多个线程访问一个资源时,就会出现竞争,举个低俗而实际的例子:N多人要上厕所,而厕所只有一个,这时就造成了竞争,如果厕所没有门,那么所有的人都可以进,这样必定造成混乱,影响正常的如厕秩序。我们如何解决呢?就是给厕所加个门。进去一个人就锁起来,别人必须等你解决了才能进去。而在多线程中为了解决这个问题引入了同步加锁方法,使用synchronized来个操作或者方法加锁。下面我们就已售票的例子来看看加锁的必要性:

 

package com.suda.thread;

public class Mythread_synchronized implements Runnable {
	private int ticket = 5;

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			if (ticket > 0) {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName() + ",正在卖出第"
						+ (this.ticket--) + "张票!");

			}
		}

	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Mythread_synchronized mt = new Mythread_synchronized();
		new Thread(mt, "售票员A").start();
		new Thread(mt, "售票员B").start();
		new Thread(mt, "售票员C").start();
	}

}运行结果:
售票员B,正在卖出第5张票!
售票员A,正在卖出第5张票!
售票员C,正在卖出第4张票!
售票员C,正在卖出第3张票!
售票员B,正在卖出第2张票!
售票员A,正在卖出第3张票!
售票员A,正在卖出第1张票!
售票员C,正在卖出第0张票!
售票员B,正在卖出第-1张票!
 

完全乱了,这就是没加锁的缺陷,十分明显,那我们看看加锁后的方法:

 

package com.suda.thread;

public class Mythread_synchronized implements Runnable {
	private int ticket = 5;

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			synchronized (this) {
				if (ticket > 0) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()
							+ ",正在卖出第" + (this.ticket--) + "张票!");

				}
			}
		}

	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Mythread_synchronized mt = new Mythread_synchronized();
		new Thread(mt, "售票员A").start();
		new Thread(mt, "售票员B").start();
		new Thread(mt, "售票员C").start();
	}

}运行结果:
售票员A,正在卖出第5张票!
售票员A,正在卖出第4张票!
售票员A,正在卖出第3张票!
售票员C,正在卖出第2张票!
售票员C,正在卖出第1张票!

  这样就达到了我们正常的结果了。这就是加锁操作,好了,今天先到这儿了,改天继续!

0
1
分享到:
评论
1 楼 liangjing23 2011-07-17  
比较简单,但是思路清晰,如果能说说输出为什么会有这样的区别就更好了。

相关推荐

    java笔试题大集合及答案(另附各大公司笔试题)

    60、java中有几种方法可以实现一...答:多线程有两种实现方法,分别是继承Thread类与实现Runnable接口 同步的实现方面有两种,分别是synchronized,wait与notify 67、线程的基本概念、线程的基本状态以及状态之间的关系

    java7源码-scn:《疯狂Java讲义》学习

    同步锁:ReentrantLock锁(具有重入性) 死锁 线程通信 线程池 2.网络编程 Java的基本网络支持: InetAddress、URLDecoder/URLEncoder、URL/URLConnection/URLPermission 2017/07/13: 1.输入输出 对象序列化、对象引用...

    java基础案例与开发详解案例源码全

    12.2.2 线程睡眠311 12.2.3 线程让步313 12.2.4 线程的加入313 12.3 线程的调度和优先级314 12.4 线程的同步315 12.4.1 线程同步的方法317 12.4.2 对象锁319 12.4.3 wait和notify方法320 12.4.4 死锁322 12.5 集合类...

    Multithreading-in-java

    Java多线程 多线程是Java的一项功能,它允许并发执行程序的两个或更多部分,以最大程度地利用CPU。 这种程序的每个部分都称为线程。 因此,线程是进程中的轻量级进程。 可以使用两种机制来创建线程: 扩展Thread类...

    疯狂JAVA讲义

    1.1 Java语言的发展简史 2 1.2 Java的竞争对手及各自优势 4 1.2.1 C#简介和优势 4 1.2.2 Ruby简介和优势 4 1.2.3 Python的简介和优势 5 1.3 Java程序运行机制 5 1.3.1 高级语言的运行机制 6 1.3.2 Java程序的...

    java 面试题 总结

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    JAVA面试题集合面试技能大全

    Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。 5. 请讲一讲析构函数和虚函数的用法和作用。 6. Error与Exception有什么区别? Error表示系统级的错误和...

    超级有影响力霸气的Java面试题大全文档

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    java核心知识点整理.pdf

    25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................

    javaSE代码实例

    第16章 多线程——Java中的并发协作 343 16.1 线程的基本知识 343 16.1.1 多线程编程的意义 343 16.1.2 定义自己的线程 344 16.1.3 创建线程对象 345 16.1.4 启动线程 347 16.1.5 同时使用多个线程 ...

    JAVA核心知识点整理(有效)

    25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................

Global site tag (gtag.js) - Google Analytics