线程(一)

线程是"进程"中某个单一顺序的控制流。也被称为轻量进程(lightweight processes),是程序执行流的最小单元,

一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。一个程序的进程会包含多个线程,一个线程就是运行在一个进程中的一个逻辑流。多线程允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立完成不同的工作。

 

进程与线程的区别:

 

1: 线程和进程一样,有独立的执行控制权,由操作系统负责调度,

2:线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信较进程简单。

3:在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。

4:由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销会小得多。

5:每个进程开始生命周期时都是单一线程,称为“主线程”,

 

 

线程的周期:

 

   1:新建

   2:就绪

   3:阻塞

   4:死亡

 

同步和死锁

 

    因为每个线程都能读写相同的共享数据。这样就带来了新的麻烦:由于数据共享会带来同步问题,进而会导致死锁的产生。

 

   什么是同步?

 

          由于一个进程中的数据对于每个线程来说是共享数据,每个线程都可以读取数据,如果不对数据做保护,则会发生多个线程同时操作同一一数据,从而发生“脏数据”的情况,因此要利用 "synchronized"  关键字来对对象保护,

 

“synchronized”关键词的作用是,确保在某个时刻只有一个线程被允许执行特定的代码块,因此,被允许执行的线程首先必须拥有对变量或对象的排他性访问权。当线程访问对象时,线程会给对象加锁,而这个锁导致其它也想访问同一对象的线程被阻塞,直至第一个线程释放它加在对象上的锁。

 

 Java中每个对象都有一把锁与之对应。但Java不提供单独的lock和unlock操作。

 

死锁是这样一种情形:多个线程都想操作一个对象数据,同时被阻塞,它们中的一个或者全部都在等待某个资源被释放,

而被等待的这个线程,

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Java中 关于线程同步的一些关键字及方法:

 

synchronized:当有多个线程同时访问共享资源的时候,需要synchronized来控制安全,此关键字可以用在synchronized方法和synchronized块,而不同的是,使用synchronized块时,一定要显示的获得该对象的锁,而方法则不需要获得。如下:

 

第一种方法:同步方法:

 

   public synchronized  void change() {

 

   }

 

 

第二种方法:同步块:

 

 public void change() {

     Synchronized(this)  {   // 显示的获得该对象的锁

 

     }

 

 }

 

第三种方法:同步静态方法

 

 public synchronized static void methodAAA() {

 

 }

 

 

第四种方法:同步类

 

public void methodBBB() {

 

    synchronized(XX.class) {

 

    }

 

}

 

这种修饰表明:同一时刻,被修饰部分只有一个对象可以运行,因为它声明是针对类的。

 

其中第一种方法与第二种方法表示的内容是相当的,第一种方法是同步当前对象,第二种方法中this表示同步当前对象,当然也可以改为其它对象

第三种方法与第四种方法表示的内容是一样的,

 

XX是这个方法所在的类,XX.class也是一个Object,类型是Class而已,在一个ClassLoader里,它是唯一的,就是独一无二的object

 

总之, synchronized的语法可以统一为:

 

 

 synchronized(XX)  {

 

    do sth;

 }

 

理解: 在XX这个object的“授权” 下执行your code . 需要注意的是,XX只能授权给一个线程,当XX授权给某个线程执行后,就不能再授权给其它线程了,只有这个线程执行完这段代码后,XX才能继续授权给其它线程,

 

也可以用另外一种方式来解释,

 

Java中每个Object都有一个对象锁,当一个线程获得该对象的锁后,就开始执行该对象的操作,直到执行完毕,才释放该对象锁,这期间如果有线程也想执行该对象中的语句,则只有等待得到该对象的锁后,才能得以执行。

 

任何一个对象都有一个标志位,有1和0两种状态,当程序执行到synchronized代码块时,就会检查对象的标志位是1还是0,如果是1则执行程序,同时将对象的标志位设置为0,其他线程执行到synchronized代码块时一看对象

标志位是0,则线程会阻塞。,一直等到对象的标志位为1再执行下面程序。

 

 

一个对象中的synchronized非静态方法,在同一时刻只能被一个线程执行,不能同时被多个线程执行。

 

 

要同步的对象,必须为一个对象,在同步执行的过程中不可以再另赋内存,同步实际上是同步对象引用指向的对象内存地址,对内存地址进行同步,如果在这其间要是赋值的话,就会出现一个新的内存地址,则同步起不到很大的意义

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值