java 多线程 day03 线程同步

package com.czbk.thread;

/**
* Created by chengtao on 17/12/3.
线程安全问题:

线程安全出现 的根本原因:
1. 存在两个或者两个以上 的线程对象共享同一个资源。
2. 多线程操作共享资源的代码 有多句。

线程安全问题的解决方案:

方式一: 可以使用同步代码块去解决。

格式:
synchronized(锁对象){
需要被同步的代码
}

同步代码块要注意的事项:
1. 锁对象可以是任意的一个对象。
2. 一个线程在同步代码块中sleep了,并不会释放锁对象。
3. 如果不存在着线程安全问题,千万不要使用同步代码块,因为会降低效率。
4. 锁对象必须是多线程共享的一个资源,否则锁不住。


方式二:同步函数 : 同步函数就是使用synchronized修饰一个函数。

同步函数要注意的事项 :
1. 如果是一个非静态的同步函数的锁 对象是this对象,
如果是静态的同步函数的锁 对象是当前函数所属的类的字节码文件(class对象)。
2. 同步函数的锁对象是固定的,不能由你来指定 的。


推荐使用: 同步代码块。
原因:
1. 同步代码块的锁对象可以由我们随意指定,方便控制。同步函数的锁对象是固定 的,不能由我们来指定。
2. 同步代码块可以很方便控制需要被同步代码的范围,同步函数必须是整个函数 的所有代码都被同步了。
*/
public class Thread03_TraditionalThread_Synchronized {
/**
* @param args
*/
public static void main(String[] args) {
new Thread03_TraditionalThread_Synchronized().init();
}

private void init(){
final Outputer outputer = new Outputer();
new Thread(new Runnable(){
public void run() {
while(true){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
outputer.output("zhangxiaoxiang");
}

}
}).start();

new Thread(new Runnable(){
public void run() {
while(true){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
outputer.output3("lihuoming");
}

}
}).start();

}

static class Outputer{

/*
直接打印,会出现同步问题,
第一个线程打印到一半的时候,
第二个线程如果获取到cpu,
那么第一个线程的字符串就只能打印一半
*/
public void output(String name){
int len = name.length();
for(int i=0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}

/*
通过同步代码块来控制,注意锁对象一定要唯一
*/
public void output1(String name){
int len = name.length();
synchronized (Outputer.class)
{
for(int i=0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}

/*
通过同步方法来控制,非静态的同步函数的锁 对象是this对象
*/
public synchronized void output2(String name){
int len = name.length();
for(int i=0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}

/*
通过同步方法来控制, 静态的同步函数的 锁对象是当前函数所属的类的字节码文件(class对象)。
*/
public static synchronized void output3(String name){
int len = name.length();
for(int i=0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
posted @ 2017-12-03 20:53  为爱奋斗不息  阅读(149)  评论(0编辑  收藏  举报