public class Test20180529001 implements Runnable{ 创建一个测试类
int i = 0; 测试类的成员变量
public static void main(String args[]){
Test20180529001 s3 = new Test20180529001(); new一个测试对象
Thread s1 = new Thread(s3); 将该对象传入Thread中
s1.start(); 先执行分支线程方法
}
public synchronized void run(){ 该线程方法为同步锁方法
i = 2000; 为i赋值2000后停止5秒钟然后进入主线程方法
try{
Thread.sleep(5000);
}
catch (Exception e){
}
}
public void w1(){ 主线程方法为非同步锁方法,可以直接读取到i的值得等于1000
try{
Thread.sleep(1000);
System.out.println(i);
}
catch (Exception e){
}
}
}
=========================================================================
总结 同步锁只针对
public synchronized void run(){
i = 2000;
try{
Thread.sleep(5000);
}
catch (Exception e){
}
} 区域内有效。非同步方法只是无法访问 synchronized 语句修饰的方法, 其他的都可以访问。
例子
public class Test20180529001 implements Runnable{
int i = 0;
public static void main(String args[]){
Test20180529001 s3 = new Test20180529001();
Thread s1 = new Thread(s3);
s1.start();
s3.w1();
}
public synchronized void run(){ 执行顺序为,先执行 run 方法 对i进行赋值2000然后停止5秒钟
i = 2000; 然后执行非同步锁方法w1 先停止1秒钟后对i进行赋值 3000
此时run线程5秒停止完毕后 执行打印输出结果为3000
Thread.sleep(5000);
System.out.println(i);
}
catch (Exception e){
}
}
public void w1(){
try{
Thread.sleep(1000);
i = 3000;
}
catch (Exception e){
}
}
}
========================================================================
解决方法是将非同步锁方法 也作为同步锁方法,第一个同步锁方法在执行中会对 对象加锁,而第二个同步锁方法在访问该对象时发现该对象已经上锁,所以会等待第一个方法执行完毕后 再执行。
import java.util.Date;
public class Test20180529001 implements Runnable{
int i = 0;
public static void main(String args[]){
Test20180529001 s3 = new Test20180529001();
Thread s1 = new Thread(s3);
s1.start();
s3.w1();
}
public synchronized void run(){
System.out.println("run上锁");
i = 2000;
for (int i = 1;i <=5 ;i++ ){
try{
Thread.sleep(1000);
System.out.println("======"+new Date()+"======");
}catch (Exception e){
}
}
System.out.println(i);
}
public synchronized void w1(){
System.out.println("w1上锁");
i = 3000;
for (int i = 1;i <=3 ;i++ ){
try{
Thread.sleep(1000);
System.out.println("======"+new Date()+"======");
}catch (Exception e){
}
}
System.out.println(i);
}
}