重庆分公司,新征程启航

为企业提供网站建设、域名注册、服务器等服务

java同步代码线程 java线程同步的方法

浅谈Java多线程的同步问题

多线程的同步依靠的是对象锁机制 synchronized关键字的背后就是利用了封锁来实现对共享资源的互斥访问

让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名申请、网络空间、营销软件、网站建设、尼木网站维护、网站推广。

下面以一个简单的实例来进行对比分析 实例要完成的工作非常简单 就是创建 个线程 每个线程都打印从 到 这 个数字 我们希望线程之间不会出现交叉乱序打印 而是顺序地打印

先来看第一段代码 这里我们在run()方法中加入了synchronized关键字 希望能对run方法进行互斥访问 但结果并不如我们希望那样 这是因为这里synchronized锁住的是this对象 即当前运行线程对象本身 代码中创建了 个线程 而每个线程都持有this对象的对象锁 这不能实现线程的同步

代码    package vista;    class MyThread implements java lang Runnable {     private int threadId;

public MyThread(int id) {      this threadId = id;     }

@Override     public synchronized void run() {      for (int i = ; i ; ++i) {       System out println( Thread ID: + this threadId + : + i);      }     }    }

public class ThreadDemo {     /**      * @param args      * @throws InterruptedException      */     public static void main(String[] args) throws InterruptedException {      for (int i = ; i ; ++i) {       new Thread(new MyThread(i)) start();       Thread sleep( );      }     }    }

从上述代码段可以得知 要想实现线程的同步 则这些线程必须去竞争一个唯一的共享的对象锁

基于这种思想 我们将第一段代码修改如下所示 在创建启动线程之前 先创建一个线程之间竞争使用的Object对象 然后将这个Object对象的引用传递给每一个线程对象的lock成员变量 这样一来 每个线程的lock成员都指向同一个Object对象 我们在run方法中 对lock对象使用synchronzied块进行局部封锁 这样就可以让线程去竞争这个唯一的共享的对象锁 从而实现同步

代码    package vista;

class MyThread implements java lang Runnable {     private int threadId;     private Object lock;

public MyThread(int id Object obj) {      this threadId = id;      this lock = obj;     }

@Override     public void run() {      synchronized (lock) {       for (int i = ; i ; ++i) {        System out println( Thread ID: + this threadId + : + i);       }      }     }    }

public class ThreadDemo {     /**      * @param args      * @throws InterruptedException      */     public static void main(String[] args) throws InterruptedException {      Object obj = new Object();      for (int i = ; i ; ++i) {       new Thread(new MyThread(i obj)) start();       Thread sleep( );      }     }    }

从第二段代码可知 同步的关键是多个线程对象竞争同一个共享资源即可 上面的代码中是通过外部创建共享资源 然后传递到线程中来实现 我们也可以利用类成员变量被所有类的实例所共享这一特性 因此可以将lock用静态成员对象来实现 代码如下所示

代码    package vista;

class MyThread implements java lang Runnable {     private int threadId;     private static Object lock = new Object();

public MyThread(int id) {      this threadId = id;     }

@Override     public void run() {      synchronized (lock) {       for (int i = ; i ; ++i) {        System out println( Thread ID: + this threadId + : + i);       }      }     }    }

public class ThreadDemo {     /**      * @param args      * @throws InterruptedException      */     public static void main(String[] args) throws InterruptedException {      for (int i = ; i ; ++i) {       new Thread(new MyThread(i)) start();       Thread sleep( );      }     }    }

再来看第一段代码 实例方法中加入sychronized关键字封锁的是this对象本身 而在静态方法中加入sychronized关键字封锁的就是类本身 静态方法是所有类实例对象所共享的 因此线程对象在访问此静态方法时是互斥访问的 从而可以实现线程的同步 代码如下所示

代码    package vista;

class MyThread implements java lang Runnable {     private int threadId;

public MyThread(int id) {      this threadId = id;     }

@Override     public void run() {      taskHandler(this threadId);     }

private static synchronized void taskHandler(int threadId) {      for (int i = ; i ; ++i) {       System out println( Thread ID: + threadId + : + i);      }     }    }

lishixinzhi/Article/program/Java/gj/201311/27441

Java 线程同步几种方式

(1)同步方法:

即有synchronized关键字修饰的方法。 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。

(2)同步代码块

即有synchronized关键字修饰的语句块。被该关键字修饰的语句块会自动被加上内置锁,从而实现同步

(3)使用特殊域变量(Volatile)实现线程同步

a.volatile关键字为域变量的访问提供了一种免锁机制

b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新

c.因此每次使用该域就要重新计算,而不是使用寄存器中的值

d.volatile不会提供任何原子操作,它也不能用来修饰final类型的变量

(4)使用重入锁实现线程同步

在JavaSE5.0中新增了一个java.util.concurrent包来支持同步。ReentrantLock类是可重入、互斥、实现了Lock接口的锁, 它与使用synchronized方法和快具有相同的基本行为和语义,并且扩展了其能力。

(5)使用局部变量实现线程同步

Java线程同步的方法

等待唤醒机制

wait():让线程等待。将线程存储到一个线程池中。

notify():唤醒被等待的线程。通常都唤醒线程池中的第一个。让被唤醒的线程处于临时阻塞状态。

notifyAll(): 唤醒所有的等待线程。将线程池中的所有线程都唤醒,让它们从冻结状体转到临时阻塞状态.

这三个方法用于操作线程,可是定义在了Object类中,为什么呢?

因为,这三个方法在使用时,都需要定义在同步中,要明确这些方法所操作的线程所属于锁。

简单说。在A锁被wait的线程,只能被A锁的notify方法唤醒。

所以必须要表示wait notify方法所属的锁对象,而锁对象可以是任意的对象。

可以被任意的对象调用的方法肯定定义在Object类中。

注意:等待唤醒机制,通常都用在同步中,因为需要锁的支持。

而且必须要明确wait notify 所作用的锁对象。

JDK1.5后的锁

在jdk1.5版本之后,

出现了一些新的特性,将原理的线程进行了改良。

在java.util.concurrent.locks包中提供了一个接口Lock。替代了synchronized。

synchronized。使用的是锁操作是隐式的。

Lock接口,使用的锁操作是显示的。

由两个方法来完成:

lock():获取锁。

unlock():释放锁。

还有一个对象,Condition.

该对象的出现替代了Object中的wait notify notifyAll这些操作监视器的方法。

替代后的方式:await signal signalAll.

Java中的线程同步与异步如何理解?

线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。

另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。

一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。

就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。

线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。

同步就是只能A走完某一段然后停下,让B开始走一段再停下,再让A走。。如此往复。简单理解就是,必须是一段程序执行完后才能执行后面的程序。。

异步就是,同一时间可能A和B同时都在往终点赶,此时不存在先后顺序,就是说,两个程序可以同时执行,称为异步。


网站标题:java同步代码线程 java线程同步的方法
本文网址:http://cqcxhl.cn/article/doioeee.html

其他资讯

在线咨询
服务热线
服务热线:028-86922220
TOP