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(); } }}
时间: 2024-08-06 23:27:49