一篇好文:java多线程机制同步原则

概括起来说,Java 多线程同步机制主要包含如下几点:
1:如果一个类包含一个或几个同步方法,那么由此类生成的每一个对象都配备一个队列用来容纳那些等待执行同步的线程。
2:对于一个线程来说,有两种途径会使其进入等待队列,一种是在其他线程调用含有同步方法的对象时,此线程正在调用这个对象的方法,另一种方法是此线程调用了 wait() 方法。
3:当一个线程从一个同步方法调用返回时,或者调用 wait() 方法时,其他线程就可以访问此对象。
4:作为总的原则,系统总是使队列中拥有最高级优先级的线程获得运行机会。
5:如果一个线程由于调用 wait() 方法而进入等待队列,那么,它必须由别的线程通过调用notify() 方法来唤醒它,才能安排它重新执行。
不可否认,上面列出的几个原则有些繁杂,但在实际处理中其实很简单,只要按照下列三条规则就可以了。
一:如果两个或多个线程修改一个对象,那么将执行修改操作的方法用关键字 synchronized 定义为同步方法。
二:如果一个线程必须等待某个对象的状态被改变,那么,此线程应在对象队列中等待,这种等待是通过进入同步方法或者调用wait() 方法来实现的。
三:每当一个方法修改了某个对象的状态的时候,这个方法就应该再调用 notify() 方法,这样给那些处于等待队列中的线程一个机会,使其能够检测环境是否已经发生了改变,从而可使其重新运行。
另补:同步机制的特点和功能是很突出的,但是他并不能解决多线程系统中的全部问题,特别是死锁问题,比如银行系统是的进入帐户问题。当一个程序在运行的时候出现了死锁,Java 系统是无能无力的。所以,用户自己设计线程的时候,要确保不出现死锁。同步问题和死锁的避免问题是有相当难度的课题哟。得花时间好好学学。

---------------------

一 线程的基本概念

线程是一个程序内部的顺序控制流.一个进程相当于一个任务,一个线程相当于一个任务中的一条执行路径.;多进程:在操作系统中能同时运行多个任务(程序);多线程:在同一个应用程序中有多个顺序流同时执行;Java的线程是通过java.lang.Thread类来实现的;JVM启动时会有一个由主方法(public static void main(){})所定义的线程;可以通过创建Thread的实例来创建新的线程;每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体,通过调用Thread类的start()方法来启动一个线程。

二 线程的创建和启动

可以有两种方式创建新的线程:
第一种:
1.定义线程类实现Runnable接口
2.Thread myThread = new Thread(target);   //target为Runnable接口类型
3.Runnable中只有一个方法:public void run();用以定义线程运行体
4.使用Runnable接口可以为多个线程提供共享的数据
5.在实现Runnable接口的类的run()方法定义中可以使用Thread的静态方法public static Thread currentThread();获取当前线程的引用

第二种:
1.可以定义一个Thread的子类并重写其run方法如:
class MyThread extends Thread {    
public void run() {...}

}    
2.然后生成该类的对象:
MyThread myThread = new MyThread();

三 线程控制的基本方法

isAlive():判断线程是否还"活"着
getPriority():获得线程的优先级数值
setPriority():设置线程的优先级数值
Thread.sleep():将当前线程睡眠指定毫秒数
join():调用某线程的该方法,将当前线程与该线程"合并",即等待该线程结束,再恢复当前线程的运行
yield():让出cpu,当前线程进入就绪队列等待调度
wait():当前线程进入对象的wait pool
notify()/notifyAll():唤醒对象的wait pool中的一个/所有等待线程

四 线程同步

实现生产者消费者问题来说明线程问题,举例如下所示:

/**
* 生产者消费者问题
*/
package com.basic.thread;
/**
* @author johnston678
*
* @version 2009-05-06
*/
public class ProducerConsumer {
/**
* @param args
*/
public static void main(String[] args) {
ProductBox pb = new ProductBox();
Producer p = new Producer(pb);
Consumer c = new Consumer(pb); Thread pThread = new Thread(p);
Thread cThread = new Thread(c);
pThread.setPriority(Thread.MAX_PRIORITY); pThread.start();
cThread.start();
}
}
/**
* 产品对象
* @author johsnton678
*/
class Product {
int id;
public Product(int id) {
super();
this.id = id;
} public String toString(){
return "Product:" + id;
}
}
/**
* 产品盒对象
* @author johnston678
*/
class ProductBox {
Product[] productbox = new Product[6];
int index = 0;
public ProductBox() {
super();
} public synchronized void push(Product p) {
while (index == productbox.length) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.notify();
productbox[index] = p;
index ++;
} public synchronized Product pop() {
while (index == 0) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.notify();
index --;
return productbox[index]; }
}
/**
* 生产者
* @author johnston678
*/
class Producer implements Runnable {
ProductBox productbox = null; public Producer(ProductBox productbox) {
super();
this.productbox = productbox;
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i=0; i<10; i++) {
Product p = new Product(i);
productbox.push(p);
System.out.println("produce:" + p); try {
Thread.sleep((int)(Math.random() * 200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} }
/**
* 消费者
* @author johnston678
*/
class Consumer implements Runnable {
ProductBox productbox = null; public Consumer(ProductBox productbox) {
super();
this.productbox = productbox;
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i=0; i<10; i++) {
Product p = productbox.pop();
System.out.println("consume:" + p); try {
Thread.sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} }

java多线程同步的更多相关文章

  1. Java多线程同步问题的探究

    一.线程的先来后到——问题的提出:为什么要有多线程同步?Java多线程同步的机制是什么? http://www.blogjava.net/zhangwei217245/archive/2010/03/ ...

  2. 转:关于JAVA多线程同步

    转:http://lanvis.blog.163.com/blog/static/26982162009798422547/ 因为需要,最近关注了一下JAVA多线程同步问题.JAVA多线程同步主要依赖 ...

  3. Java多线程-同步:synchronized 和线程通信:生产者消费者模式

    大家伙周末愉快,小乐又来给大家献上技术大餐.上次是说到了Java多线程的创建和状态|乐字节,接下来,我们再来接着说Java多线程-同步:synchronized 和线程通信:生产者消费者模式. 一.同 ...

  4. Java多线程同步 synchronized 关键字的使用

    代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A, ...

  5. Java多线程---同步与锁

    一,线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 二.同步和锁定 1.锁的原理 Java中每个对象都有一个内置锁. 当程序运行到非静态的synchronized同步方法上时,自动 ...

  6. Java多线程同步的方法

    一 synchronized关键字 1.synchronized实现原理: ---基于对象监视器(锁) java中所有对象都自动含有单一的锁,JVM负责跟踪对象被加锁的次数.如果一个对象被解锁,其计数 ...

  7. Java 多线程同步的五种方法

    一.引言 闲话不多说,进入正题. 二.为什么要线程同步 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常.举个例子 ...

  8. Java多线程同步问题:一个小Demo完全搞懂

    版权声明:本文出自汪磊的博客,转载请务必注明出处. Java线程系列文章只是自己知识的总结梳理,都是最基础的玩意,已经掌握熟练的可以绕过. 一.一个简单的Demo引发的血案 关于线程同步问题我们从一个 ...

  9. java多线程同步(转)

    原文地址:http://developer.51cto.com/art/201509/490965.htm 一.场景 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时, ...

随机推荐

  1. git 克隆本地仓库

    如果要从本地仓库克隆到另一个地方使用如下命令 git clone d:/SourceRepository d:/DestinationRepository d:/SourceRepository:本地 ...

  2. JVM学习之常用概念

    方法区     当JVM使用类装载器装载某个类时,它首先要定位对应的class文件,然后读入这个class文件,最后,JVM提取该文件的内容信息,并将这些信息存储到方法区,最后返回一个class实例. ...

  3. QF——iOS代理模式

    iOS的代理模式: A要完成某个功能,它可以自己完成,但有时出于一些原因,不方便自己完成.这时A可以委托B来帮其完成此功能,即由B代理完成.但是这个功能不是让B随随便便任其完成.此时,会有一个协议文件 ...

  4. QF——OC内存管理详解

    堆的内存管理: 我们所说的内存管理,其实就是堆的内存管理.因为栈的内存会自动回收,堆的内存需要我们手动回收. 栈中一般存储的是基本数据类型变量和指向对象的指针(对象的引用),而真实的对象存储在堆中.因 ...

  5. STL源码剖析 迭代器(iterator)概念与编程技法(三)

    1 STL迭代器原理 1.1  迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型,STL设计的精髓在于,把容器(Containers)和算法(Algorithms)分开,而迭代器(i ...

  6. C#控件、窗体置顶

    //控件置于顶层和底层 panel.BringToFront();//置于顶层 panel.SendToBack();//置于底层 //窗体置顶 TopMost = true;

  7. str系列---字符串函数

    1. strcat extern char *strcat(char *dest,char *src); 把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'. 返回指 ...

  8. 【POJ】2528 Mayor's posters ——离散化+线段树

    Mayor's posters Time Limit: 1000MS    Memory Limit: 65536K   Description The citizens of Bytetown, A ...

  9. Linux一键安装web环境全攻略(阿里云服务器)

    摘自阿里云服务器官网,此处 一键安装包下载: 点此下载 安装须知 1.此安装包可在阿里云所有linux系统上部署安装,此安装包包含的软件及版本为: nginx:1.0.15.1.2.5.1.4.4 a ...

  10. EF简介

    EF:EF是 asp.net的一套ORM框架. ORM: 广义上:ORM指的是面向对象的模型和关系型数据库的数据库之间的相互转换; 狭义上:ORM可以被认为是,基于关系型数据库的数据存储,实现一个虚拟 ...