• Java 多线程分析 (三) --- synchronize 同步


    两个线程同时访问同一个资源,发生数据不同,解决方法:某个线程运行过程不能被其他线程访问;

    1.调用Java.lang.Thread类过程中Runnable接口,在Run方法进行重写(采用接口的方式)

    2.采用继承的方式**** extends Thread,在子类直接调用thread 的run方法(采用继承的方式,在子类)

     3.static关键词:1.static声明变量为静态成员变量,定义必须初始化(存放数据区,分配地址区域),该类公用变量,2.static方法为静态方法:不会将对象引用方法传递给他,在static方法中不可访问非static成员

    4.如下面这个问题当不加上synchrenized锁的方法,当在其访问的过程中,T1线程非常有可能被T2线程给打断,加上被锁的条件

     1 package TestThread;
     2 
     3 public class TestSync implements Runnable {
     4     Timer time1=new Timer();
     5     public static void main(String[] args){
     6         TestSync test=new TestSync();
     7         Thread t1=new Thread(test);
     8         Thread t2=new Thread(test);
     9         t1.setName("t1");
    10         t2.setName("t2");
    11         t1.start();
    12         t2.start();
    13         //为什么会出现这样情况在于t1,t2访问同一个内存,当t1运行num++(num=1)发生了1毫秒的睡觉,由于cpu
    14         //运行时间<<sleep(1)时间,main进程马上运行t2.start();同时num=1+1=2,所以输出t1和t2中num=2(自己猜猜)
    15         //就算是把sleep去掉,同样一样结果,说明在t1运行过程中被t2打断了,锁定当前对象
    16     }
    17     public void run(){
    18         time1.add(Thread.currentThread().getName());
    19         //为什么会自动执行run方法:Thread 类的过程使用的是接口模式,对Thread中run方法的重写,
    20         //Thread t1=new Thread(test);在采用t1.start();方法会自动执行run中被重写的方法,进程启动一种方式
    21     }
    22 
    23 }
    24 class Timer{
    25     private static int num=0;
    26     public synchronized void add(String name)
    27     {
    28         
    29     
    30     //    synchronized (this){
    31         num++;
    32         try{Thread.sleep(0);}
    33         catch(InterruptedException e){}
    34         System.out.println(name+",你是第"+num+"个使用timer的线程");
    35     //    }
    36     }
    37 }

    5.写一个死锁的原理

     

    死锁:现在A、B两个进程,A进程完成要C,D连个对象进行锁定,在执行过程当中,A对C进程锁定定,同一时间内D对象被另外一个进程锁定,。(同样B进程需要两个对象完成,先执行的是对D对象锁定)这样形成了悖论无非正常运行下去。

     1 //此程序千万不要运行,只是模拟死锁的概念
     2 public class TestDeadLock implements Runnable {
     3 public int flag=1;
     4 static Object o1=new Object(),o2=new Object ();
     5 
     6 public void run()
     7 {
     8     if(flag==1)
     9     {
    10         synchronized(o1)
    11         {
    12             try{
    13                 Thread.sleep(500);
    14             }
    15             catch(Exception e){
    16                 e.printStackTrace();
    17             }
    18         }
    19         synchronized(o2){
    20             System.out.println("1");
    21         }
    22     }
    23     if(flag==0)
    24     {
    25         synchronized(o2)
    26         {
    27             try{
    28                 Thread.sleep(500);
    29             }
    30             catch(Exception e){
    31                 e.printStackTrace();
    32             }
    33         }
    34         synchronized(o1){
    35             System.out.println("2");
    36         }
    37     }
    38 
    39 }
    40 public static void main(String [] args){
    41     TestDeadLock td1=new TestDeadLock();
    42     TestDeadLock td2=new TestDeadLock();
    43     td1.flag=1;td2.flag=2;
    44     Thread t1=new Thread(td1);
    45     Thread t2=new Thread(td2);
    46     t1.start();
    47     t2.start();
    48 }
    49 }

    解决死锁问题:不死锁较小程序,扩大锁的空间,

    锁只是说:只是会锁定此方法,不会锁定其他方法,在m2(没有锁定)方法中修改b=2000,那么根据原理来说,在m1方法中因为在此方法中锁定,但是在内存中被修改,所以m1输出过程b=2000;(m1加锁,m2方法没有加锁)都可以对b内存访问,会发生修改值

     II.如果m1和m1同时加锁,执行哪个方法过程,会锁定b,在同一时间只能够运行访问一次

  • 相关阅读:
    一道Twitter面试题
    聊下并发和Tomcat线程数(错误更正)
    Entity Framework系列教程汇总
    SqlServer基础汇总
    .Net Core中间件和过滤器实现错误日志记录
    快速掌握mongoDB(六)——读写分离的副本集实现和Sharing介绍
    快速掌握mongoDB(五)——通过mongofiles和C#驱动操作GridFS
    快速掌握mongoDB(四)—— C#驱动MongoDB用法演示
    快速掌握mongoDB(三)——mongoDB的索引详解
    快速掌握mongoDB(二)——聚合管道和MapReduce
  • 原文地址:https://www.cnblogs.com/woainifanfan/p/5771112.html
Copyright © 2020-2023  润新知