一篇好文: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(); } } } }