线程同步
1、线程同步的目的是为了保护多个线程访问一个资源时对资源的破坏。
2、线程同步方法是通过锁来实现,每个对象都有切仅有一个锁,这个锁与一个特定的对象关联,线程一旦获取了对象锁,其他访问该对象的线程就无法再访问该对象的其他同步方法。
实现同步机制的两个方法
1。同步代码块:
synchronized(同一个数据){} 同一个数据:就是N条线程同时访问一个数据。
2。
同步方法:
public synchronized 数据返回类型 方法名(){}
就是使用 synchronized 来修饰某个方法,则该方法称为同步方法。对于同步方法而言,无需显示指定同步监视器,同步方法的同步监视器是 this 也就是该对象的本身(这里指的对象本身有点含糊,其实就是调用该同步方法的对象)通过使用同步方法,可非常方便的将某类变成线程安全的类,具有如下特征:
1,该类的对象可以被多个线程安全的访问。
2,每个线程调用该对象的任意方法之后,都将得到正确的结果。
3,每个线程调用该对象的任意方法之后,该对象状态依然保持合理状态。
注:synchronized关键字可以修饰方法,也可以修饰代码块,但不能修饰构造器,属性等。
实现同步机制注意以下几点: 安全性高,性能低,在多线程用。性能高,安全性低,在单线程用。
synchronized(同一个数据){} 同一个数据:就是N条线程同时访问一个数据。
2。
同步方法:
public synchronized 数据返回类型 方法名(){}
就是使用 synchronized 来修饰某个方法,则该方法称为同步方法。对于同步方法而言,无需显示指定同步监视器,同步方法的同步监视器是 this 也就是该对象的本身(这里指的对象本身有点含糊,其实就是调用该同步方法的对象)通过使用同步方法,可非常方便的将某类变成线程安全的类,具有如下特征:
1,该类的对象可以被多个线程安全的访问。
2,每个线程调用该对象的任意方法之后,都将得到正确的结果。
3,每个线程调用该对象的任意方法之后,该对象状态依然保持合理状态。
注:synchronized关键字可以修饰方法,也可以修饰代码块,但不能修饰构造器,属性等。
实现同步机制注意以下几点: 安全性高,性能低,在多线程用。性能高,安全性低,在单线程用。
关键代码如下:
编写打印机类:Printer 定义两个方法
package cn.d.happy; public class Printer { Object o=new Object(); //或在void前加synchronized public void print1(){ //同步代码块 synchronized (o){ System.out.print("线"); System.out.print("程"); System.out.print("同"); System.out.print("步"); System.out.println(); } } public void print2(){ synchronized (o){ System.out.print("噢"); System.out.print("呵"); System.out.println(); } } }
定义两个线程类 并重写run方法。继承Thread 和 实现Runnable接口 通过for循环遍历次数
package cn.d.happy; public class MyThread extends Thread{ public Printer print; @Override public void run() { //必须有该类的对象实例 for (int i = 1; i <=10; i++) { print.print1(); } } }
package cn.d.happy; public class MyThread2 implements Runnable{ public Printer print; @Override public void run() { for (int i = 1; i <=10; i++) { print.print2(); } } }
测试类 创建打印机对象 以及两个线程对象并进行赋值
package cn.d.happy; public class Test { public static void main(String[] args) { //购买一个打印机 Printer p=new Printer(); //创建第一个线程对象 并且给属性赋值 MyThread t1=new MyThread(); t1.print=p; t1.start(); //03.创建第二个线程对象 并且给属性赋值 MyThread2 t2=new MyThread2(); t2.print=p; Thread tt=new Thread(t2); tt.start(); } }
实现效果: