java随笔

多线程

2017-07-09  本文已影响2人  71150ce14a00

一个进程包含多个线程
线程也叫子程序
多线程:一个进程中同事运行多个线程或多个任务
好处:提高运行效率
多线程运行时,每一个线程多会在内存中开辟一个属于自己的独立空间,每一个线程之间互不干扰
jvm:多线程,main主线程,垃圾回收
并行:某一时间发生的事情
并发:某一时间段发生的事情
线程有两种方式:

第一种:线程类

1.继承Thread方法,重写run方法添加线程任务,创建对象启动子类的实例start()方法,线程启动必须调用系统资源,在内存中开辟独立空间
注意:
1.调用stat() 就会立刻调用系统资源,开辟独立空间,线程启动
2.当调用start()方法启动线程后,底层会立刻调用run方法来执行任务
3.同一个线程不可以开启多次,一个线程开辟一个空间,同一个线程不可以开辟多个空间
获取线程名字:getName
设置线程名字:setNmae
获取当前正在执行的线程:Thread.currentThread()

 class MyThread extends Thread{
   public void run(){
         for(int i = 0; i<10;i++)
                System.out.println(Thread.currentThread().getName+i);
    }
  }
   MyThread t = new MyThread();
   t.setName("one");
   t.start();
第二种:任务类 (常用)

实现Runnable接口,复写fun接口,创建任务类对象,创建Thread对象传入人物类对象,start启动线程

 class MyThread implements Runnable{
      public void run(){
         for(int i = 0; i<10;i++)
         System.out.println(Thread.currentThread().getName()+i);
   }
  }
       MyThread t = new MyThread();
       Thread tt = new Thread(t,"t");
         tt.start();

为什么第二种是常用的:
1.第二种改变了单继承的局限性
2.耦合度:依赖关系
第一种耦合度高,第二种耦合度低

线程休眠:
sleep(long)
Thread.sleep(1000)
sleep和wait区别:
sleep达到时间自动唤醒线程,而wait需要手动唤醒

线程安全:
同步代码块:

  synchronized(任意对象或者锁)对象必须唯一
   {
   }

在同一任务中,锁可以是任意对象,但一定要唯一
当一个线程进入到同步代码快中,那么这个线程会立刻获取唯一的一把锁,那么其他线程只能等待这个线程释放后才能进入到同步代码块中操作共享资源

卖票例子:

    class MyThread implements Runnable{
      private int count = 100;
      Object obj = new Object();    
      public void run(){
             while(true){
                 synchronized(obj){
                     if(count > 0){
                        System.out.println(Thead.currentThread().getName()+i);
                       count --;
                     }
                 }
              }
     }
     }

    MyThead t = new MyThrad();
        new Thread(t,"窗口1").start();
         new Thread(t,"窗口2").start();
        new Thread(t,"窗口3").start();

线程声明周期图:


1.PNG

如果一个方法中所有的内容都需要添加在同步代码快中,可以在方法上添加锁
非静态方法:public synchronized void method(){}
静态方法:public synchronized static void methord(){}
同步锁对象可以任意,但必须唯一
非静态同步方法锁是this
静态同步方法锁是当前类的字节码文件对象类名.class文件

线程安全出现的原因
1.多个线程
2.多个线程操作共同资源
3.操作资源代码多行
4.CPU随机切换

同步代码块的好处和弊端
弊端:使用同步代码块影响程序执行效率,每次cpu运行到同步代码块的时候都需要判断有没有线程在代码快中
好处:加了同步代码块保证多线程操作共享数据的安全

单例:

饿汉式:没有线程安全问题
懒汉式:有线程安全问题

class Single{
   private Single(){}
   private static Single s = null;
   private static Object obj = new Object();
   pubic static Single getInstance(){
     if(s == null) //着个代码只是为了提高效率
         synchronized(obj){
           if(s = null){
                 s = new Single();
           }
         }
       return s;
   }  
 }

死锁问题:
多个线程操作共享资源产生互相等待现象

2.PNG 3.PNG

如何避免死锁问题:
避免同步嵌套,保证锁唯一

线程间通信:

wait()
notify()
notifyAll()
线程有很多,控制线程的是锁对象,而锁的对象是任意的对象,能够被任意对象调用的方法,所以在Objec类中
注意: 在同步代码块里调用方法,锁一定和同步有关,在同步中才有锁

  1. 当以个线程处于等待状态,那么就会立刻释放锁
    2.当一个线程处于等待状态,cpu不会执行该线程
    3.即使一个线程被唤醒,但是没有锁,那么这个线程也不会被执行

jdk5以后对同步和线程通信进行升级:
lock对synchronized的升级
Lock l =new ReentrantLock();
l.lock();
需要加锁的的内容
l.unlock();

Condition c = l.newCondition();
condition接口对线程通信的升级
await() ----------> wait
await(time,unit)
singnal()--------->notify
singnalAll() ----->notifyAll

注意:
Lock 和condition 一起使用, synchronized和 wait() notify ,notifyAll 一起使用

上一篇 下一篇

猜你喜欢

热点阅读