2021-01-26

2020.01.26 星期二

多线程

1. 多线程

1. 1 基本概念

程序: 为了实现某个特定的任务,使用某种编程语言编写的一组指令集合(静态)

进程: 正在运行的一个程序,是一个动态过程,具有生命周期,是资源分配的基本单位

线程:进程细分为线程,线程是一个程序内部的一条执行路径

  1. 线程是调度和执行的基本单位
  2. 同一个进程下的线程共享资源(相同的内存单元/内存地址空间)
  3. 每个线程拥有独立的运行栈和程序计数器(PC)

并行: 多个人(CPU)同一时间干多种事(任务)

并发:一个人(CPU)同一时间(时间片)干多种事(任务)

为什么要使用多线程?

  1. 提高应用程序的响应速度(图形化界面),增强用户体验
  2. 提高计算机CPU利用率
  3. 改善程序的结构,将长且复杂的进程划分为多个线程,独立运行,利于理解和修改

1.2 线程的创建和使用

  1. 继承Thread类,重写run方法
public class ThreadExtendsThread extends Thread{
  @Override
  public void run(){
    //重写run()方法
  }
}

​ 使用:

public static void main (String[] args){
  ThreadExtendsThread thread = new ThreadExtendsThread();
  thread.start();
  //start(),创建一个线程并执行run()方法
  //如果直接执行thread.run(),则只是简单的执行了thread对象的run()方法,没有开启一个线程
}
//一个Thread子类对象,一个线程

//Thread类的常用方法
//1.void start()
//2.void setName(String name)
//3.String getName()
//4.Thread currentThread()
//5.void yield()
//6.static void sleep(long millis)
//7.join()
//8.stop()
//9.boolean isAlive()
  1. 实现Runnable接口,重写run方法
public class ImplementRunnable implements Runnable{
	@Override
	public void run(){
		//重写run()方法
	}

}

​ 使用:

public void main(String[] args){
	ImplementRunnable iRunnalbe = new ImplementRunnable();
	Thread thread = new Thread(iRunnable);
	thread.start();
}
//一个Thread类对象,一个线程

1.3 线程的生命周期

  1. 新建
  2. 就绪
  3. 运行
  4. 阻塞
  5. 死亡

1.4 线程的同步

  1. 什么是线程安全?

当某个数据同时被多个线程访问,很有可能出现线程不安全的问题,例如多个线程同时对一个数据进行增加,删除,修改等操作

  1. 实现线程安全的思路?

对访问共享数据的线程进行限制,如当某个线程在访问共享数据时,其他线程无法其进行任何操作(读,写…),保证了数据的安全性,称为线程的同步

  1. 实现线程安全的方法?

    1. 同步代码块
    public void run(){
      //如果实现多线程的方式是继承Thread类方式,
      //则同步监视器(锁)应该是类.class(保持唯一)
    	synchronized(本类.class){
    		//多线程代码;
    	}
      
      //如果实现多线程的方式是实现Runnable接口,
      //则同步监视器(锁)应该是this,(保持唯一)
      synchronized(this){
        //多线程代码;
      }
    }
    

    ​ b. 同步方法

    public synchronized void run(){
    	//如果实现多线程的方式是继承Thread类
    	//则同步方法应该是静态的,只有一份,同步监视器类.class
      
      //如果实现多线程的方式是实现Runnable接口
      //则同步监视器应该是this
    }
    
  2. 释放锁的操作

    1. 程序正常执行
    2. wait() ==sleep不会释放锁
    3. break/return
    4. 未处理的Exception/Error
  3. 不会释放锁的操作

    1. sleep()
    2. 死锁
    3. yield
    4. suspend()
  4. 什么是死锁?

    双方都占用互相需要的资源不放手,都在等待对方放手

public void main(String[] args){
	StringBuffer s1 = new StringBuffer();
	StringBuffer s2 = new StringBuffer();
	new Thread(){
		@Ovrride
		public void run(){
			synchronized(s1){
				s1.append("a");
				s2.append("1");
        Thread.sleep(10);//此时锁住s1,s2暂时自由
        //睡醒了,锁住s1,等待s2
				synchronized(s2){
					s1.append("b");
					s2.append("2");
				}
			}
		}
	}.start();
	
	new Thread(new Runnable(){
		@Override
		public void run(){
			synchronized(s2){
				s1.append("c");
				s2.append("3");
        Thread.sleep(10);
        //当s1被锁住,s2暂时自由,
      //这个线程很容易执行到这,
      //锁住s2,等待s1
				synchronized(s1){
					s1.append("d");
					s2.append("4");
				}
			}
		}
	}).start();



}

​ 解决方法:

  1. 专门的算法/原则

  2. 减少同步资源的定义

  3. 减少嵌套同步

  4. JDK5.0新增的线程同步机制*—通过显式定义同步锁对象(Lock对象)来实现同步

    1. java.util.concurrent.locks.Lock接口:
    2. 控制多个线程对共享资源进行访问的工具
    3. 提供了堆共享资源的独占访问
    4. 每次只有一个线程对Lock对象加锁
  5. Lock锁的使用

public void main(String[] args){
	//1.创建锁对象
	Lock lcok = new ReentrantLock();
	//2.访问共享数据前,手动上锁
	lock.lock();
	try{
		//访问共享数据
	}
	//3.为了确保解锁操作一定被执行,所以放在finally模块中
	finally{
		lock.unlock();
	}
}
  1. SynchronizedLock的对比
    • Synchronized是隐式锁,进出作用域相当于上锁解锁
    • Lock是全手动,上锁lock.lock()解锁lock.unlock()全手动
    • Lock只有代码锁,Synchronized有代码锁和方法锁
    • Lock锁性能更好,因为JVM花费较少时间来调度线程,且其具有较高可扩展性(提供更多子类)
    • 使用建议:Lock—>同步代码块—>同步方法

1.5 线程的通信

1. wait() 释放锁(故调用此方法前提是拥有锁),当前线程挂起并放弃CPU,同步资源并等待,让别的线程可访问并修改共享资源

2. notify() 唤醒正在排队等待同步资源的线程(优先级最高者先结束等待,若无最高,随机唤醒)
3. notifyAll()唤醒所有正在排队等待同步资源的线程(全部)
4. yield() 让步给更高优先级/相同优先级的线程
5. join() 调用线程将被阻塞,直到join()方法加入的join线程执行完为止
  • wait(),notify()notifyAll()都只能在同步方法/同步代码块中使用否则会出现java.lang.IllegalMonitorStateException异常

###1.6 JDK5.0新增的线程创建方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
2021-03-26 20:54:33,596 - Model - INFO - Epoch 1 (1/200): 2021-03-26 20:57:40,380 - Model - INFO - Train Instance Accuracy: 0.571037 2021-03-26 20:58:16,623 - Model - INFO - Test Instance Accuracy: 0.718528, Class Accuracy: 0.627357 2021-03-26 20:58:16,623 - Model - INFO - Best Instance Accuracy: 0.718528, Class Accuracy: 0.627357 2021-03-26 20:58:16,623 - Model - INFO - Save model... 2021-03-26 20:58:16,623 - Model - INFO - Saving at log/classification/pointnet2_msg_normals/checkpoints/best_model.pth 2021-03-26 20:58:16,698 - Model - INFO - Epoch 2 (2/200): 2021-03-26 21:01:26,685 - Model - INFO - Train Instance Accuracy: 0.727947 2021-03-26 21:02:03,642 - Model - INFO - Test Instance Accuracy: 0.790858, Class Accuracy: 0.702316 2021-03-26 21:02:03,642 - Model - INFO - Best Instance Accuracy: 0.790858, Class Accuracy: 0.702316 2021-03-26 21:02:03,642 - Model - INFO - Save model... 2021-03-26 21:02:03,643 - Model - INFO - Saving at log/classification/pointnet2_msg_normals/checkpoints/best_model.pth 2021-03-26 21:02:03,746 - Model - INFO - Epoch 3 (3/200): 2021-03-26 21:05:15,349 - Model - INFO - Train Instance Accuracy: 0.781606 2021-03-26 21:05:51,538 - Model - INFO - Test Instance Accuracy: 0.803641, Class Accuracy: 0.738575 2021-03-26 21:05:51,538 - Model - INFO - Best Instance Accuracy: 0.803641, Class Accuracy: 0.738575 2021-03-26 21:05:51,539 - Model - INFO - Save model... 2021-03-26 21:05:51,539 - Model - INFO - Saving at log/classification/pointnet2_msg_normals/checkpoints/best_model.pth 我有类似于这样的一段txt文件,请你帮我写一段代码来可视化这些训练结果
02-06

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值