2 线程的基础知识(中)

原创 2016年08月31日 16:50:46

Continued Chapter,Sleep()和Wait()的相同与区别?

相同:1从使用结果:都会让程序从从运行状态(Running)到阻塞状态(Blocked)。

区别:1Sleep()属于Thread类下的方法,

static void sleep(long millis)
          在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
Wait()属于Object类方法

Continued Chapter

 void wait()
          在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
 void wait(long timeout)
          在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。
 void wait(long timeout, int nanos)
          在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
2 关于面试中经常问到这两个有关锁的问题

首先锁是什么?为什么要这个锁?锁(Lock):你可以把它想象成一个权限,只有当你拿到这个权限的时候你才能用。好了这个权限是什么呢?应为在线程当作,我们往往会编写大量的线程,这些线程不可能每个都重新开资源,把相同的资源拿出来,我们来同步代码块,这些代码块之类的就是锁了。

拿个别人的列子:

我要输出1到10000,建立10个线程来输出。
public class ThreadTest1 extends Thread {   
    private int threadNo;   
    public ThreadTest(int threadNo) {   
        this.threadNo = threadNo;   
    }   
    public static void main(String[] args) throws Exception {   
        for (int i = 1; i < 10; i++) {   
           new ThreadTest(i).start();   
            Thread.sleep(1);   
        }   
     }   
    
    @Override  
     public void run() {   
        for (int i = 1; i < 1000; i++) {   
            System.out.println("No." + threadNo + ":" + i);   
        }   
     }   
 }  
这个只是简单的重写run()方法,再来看看带Synchonized()和Lock()
public class ThreadTest extends Thread {   
    private int threadNo;   
    public ThreadTest(int threadNo) {   
        this.threadNo = threadNo;   
    }   
    public static void main(String[] args) throws Exception {   
        for (int i = 1; i < 10; i++) {   
           new ThreadTest(i).start();   
            Thread.sleep(1);   
        }   
     }   
    
    @Override  
     public synchronized void run() {   
        for (int i = 1; i < 10000; i++) {   
            System.out.println("No." + threadNo + ":" + i);   
        }   
     }   
 }  
这个使用了synchronized()同步方法的,Java中用同步监视器来解决进程并发造成的异常,我们上面用的是同步方法(讲下怎么使用呢就是用synchronized关键字来修饰方法,这样就称为同步方法)。虽然这样我们已经觉得很方便了,但是人的创造是无穷的,后来人们有在此基础上,提出了锁的概念,这个具有更强大的功能。

import java.util.concurrent.locks.ReentrantLock;

public class ThreadTest2 extends Thread {   
	 private int threadNo; 
	 private ReentrantLock lock=new ReentrantLock();
	 public ThreadTest2(int threadNo) {   
	  this.threadNo = threadNo;   
	     }   
	public static void main(String[] args) throws Exception {   
	    
	     for (int i = 1; i < 10; i++) {     
	  new ThreadTest2(i).start();   
	      Thread.sleep(1);   
	     }   
	  }     
	public void run() {     
	 lock.lock();
	 
	 try{   
	      for (int i = 1; i < 1000; i++) {   
	       System.out.println("No." + threadNo + ":" + i);   
	    }      
	 }  
	 finally
	 {
		 lock.unlock();
	 }
	 }   
	 }
这3个代码效果是一样的,但是我们发现这不是我们想要的。以为经过对比,我们发现无论有没有加synchronized()同步方法,还是直接上锁,我们都对的是run()方法,换个说法,线程自身作为对象锁,这显然没用。

如果我们要对线程进行同步,就要对同步对象进行上锁,这些对象需要共享且是唯一的,如何进行上锁呢?

public class ThreadTest extends Thread {   
    private int threadNo;   
    private  String men;
    public ThreadTest(int threadNo,String men) {   
        this.threadNo = threadNo;   
        this.men=men;
    }   
    public static void main(String[] args) throws Exception {   
    String men=new String();
        for (int i = 1; i < 10; i++) {   
           new ThreadTest(i,men).start();   
            Thread.sleep(1);   
        }   
     }   
    
    @Override  
     public void run() { 
    	synchronized(men){
        for (int i = 1; i < 1000; i++) {   
            System.out.println("No." + threadNo + ":" + i);   
        }  
    	}
     }   
 }  
这个就可以实现每个线程单独打印出1到1000个数。

讲了这么多,那Sleep()和Wait()在对待锁到底有什么区别呢?

Sleep()执行的时候是不会释放锁的,该监控对象依然存在,只是时间到了才会释放。

而Wait()会放弃对象锁,进入等待此对象的等待池。除非被noifty()或者noiftyAll()唤醒。



Continued Chapter
版权声明:本文为博主原创文章,未经博主允许不得转载。

C#线程的基础知识

线程的创建1、ThreadStart委托的使用Thread th1 = new Thread(MyThread.ThreadMethod);MyThread obj = new MyThread();...
  • aofengdaxia
  • aofengdaxia
  • 2015年07月03日 17:59
  • 1516

Java笔记 - 线程基础知识

进程是一个执行中程序的实例,是操作系统进行资源分配和调度的一个独立单元。线程是进程中一个单一的程序控制流,是 CPU 调度和分派的基本单元。进程在执行时拥有独立的内存空间,进程中的线程可以共享进程的内...
  • yanshazi
  • yanshazi
  • 2016年04月05日 13:01
  • 2338

2.2数据通信的基础知识

典型的数据通信模型 输入信息–源点—输输入数据–发送器–发送信号–传输系统-=-接收信号–接收器–输出数据–终点–输出信息。 相关术语: 通信的目的是传送消息。消息,对用户有用的信息 数据...
  • liuyuzhu111
  • liuyuzhu111
  • 2015年11月30日 13:45
  • 257

数据结构基础知识(2)

内容接自《数据结构基础知识(1)》。。。 链表的分类 单链表       单链表是一种链式存取的结构,为找第 i 个数据元素,必须先找到第 i-1 个数据元素。图中阴影区域表示数据域,空白区表示...
  • happylee6688
  • happylee6688
  • 2013年04月05日 17:14
  • 4315

C++ 线程基础

线程可以说是轻型的进程 多线程共享进程的地址空间和资源使得线程的上下文切换优于进程 由于线程共享资源就会有抢占资源的情况主要的手段有 互斥锁 ,条件变量 ,信号量等等 简单回顾下C++ 多线程 ...
  • cszskkk1
  • cszskkk1
  • 2016年10月19日 22:38
  • 124

Java多线程完整版基础知识

Java多线程完整版基础知识 (翟开顺由厚到薄系列) 1.前言 线程是现代操作系统中一个很重要的概念,多线程功能很强大,java语言对线程提供了很好的支持,我们可以使用java提供的thread类很容...
  • T1DMzks
  • T1DMzks
  • 2016年07月13日 00:39
  • 8396

多线程基础知识第二篇:线程常用方法及各种状态

本篇主要介绍一下Thread类的方法以及探究一下线程的状态。 首先,Thread类常用的静态方法: 1.Thread.activeCount(),得到存活的线程数,返回值是int类型; 2.Threa...
  • koushr
  • koushr
  • 2015年07月15日 12:03
  • 1190

线程基础:线程(2)——JAVA中的基本线程操作(上)

从这篇文章开始。我们介绍线程的工作原理。
  • yinwenjie
  • yinwenjie
  • 2016年01月05日 17:35
  • 6504

java创建两个线程的方法和它们的区别

Java提供了线程类Thread来创建多线程的程序。其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象。每个Thread对象描述了一个单独的线程。要产生一个线...
  • abc19900828
  • abc19900828
  • 2012年07月31日 15:01
  • 2461

Google面试题—有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD

有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD。初始都为空。现要让四个文件呈如下格式:A:1 2 3 4 1 2....B:...
  • lilien1010
  • lilien1010
  • 2012年10月27日 19:56
  • 7594
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:2 线程的基础知识(中)
举报原因:
原因补充:

(最多只允许输入30个字)