最近对java的基础知识进行了一次回顾,可是在看到线程安全的时候始终感觉到自己现在理解的没有以前深刻了..所以现在记下来防止以后再忘记
首先线程不用多说..要实现一个线程基本上有两种方式一种是继承Thread类..另外一种就是实现Runnable接口..当然或许还有人说可以实现Callable接口.当然,我也在其他书上看到过这种说法..不过还没自己去看..不过了解过java的应该知道实现Runnable接口是完成线程的最好的选择了..具体我就不解释了..
我最主要的是想记录下来我关于同步的问题..
如果一个类实现了Runnable的接口,同时又有访问类变量的时候就需要在某个访问或者修改类变量的函数上加上static 和 synchronized 修饰符
public synchronized static void test() { }或者在方法体中的代码块中加入以该类的对象锁比如:
public void test1() {
synchronized (SynchronizedStatic.class){}
}
这样才能保证当多个线程并发访问该类属性的时候,实现线程安全..当然,线程安全指的是当有多个线程并发访问同一个数据的时候才考虑的一种情况.如果仅仅是像做实验那样,仅仅想看一下线程到底是个什么东西的话..比如
public class SynchronizedStatic implements Runnable { static boolean staticFlag = true; public synchronized static void test() { for (int i = 0; i < 100; i++) { System.out.println("test" + Thread.currentThread() + ":" + i); } } public void test1() { synchronized (SynchronizedStatic.class) { for (int i = 0; i < 100; i++) { System.out.println("test1" + Thread.currentThread() + ":" + i); } } }
@Override public void run() { // TODO Auto-generated method stub test1(); }
这样的话在main方法中}
这样的话并只是想让该测试程序执行完一个线程的打印后再执行另外一个.因为是同一个对象ss,所以方法中完全可以使用该对象的锁即this来完成对代码块的同步..public class Test { public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub SynchronizedStatic ss = new SynchronizedStatic(); new Thread(ss).start(); new Thread(ss).start(); } }
还有就是一本书中所说的当一个线程进入同步方法或者同步代码块之前必须先获得同步方法或者代码块的同步监听器(就是对象锁),对于同步代码块而言程序必须为其显式指定对象锁.而对于同步静态方法默认使用的是该类作为对象锁的.而对于同步非静态方法默认使用该对象来完成对象锁