软件构造相关

名词解释
进程(Process)和线程(thread):并发编程的两个基本单元。进程:(1)和同一个机器上的其他进程是彼此隔离的。(2)拥有私有的内存空间,运行时不能共享变量。(3)通过IPC(pipe/socket)进行通信。线程:(1)共享所在进程的内存空间(2)共享可变对象的共享时,需要同步(使用synchronization关键字维护线程安全)。(3)有独立的运行时栈,就像一个普通的函数。(4)杀死线程不安全。
Concurrent(并发):在单核机器上,“多进程”并不是真正的多个进程在同时执行,而是通过CPU时间分片,操作系统快速在进程间切换而模拟出来的多进程。(此处默认是一个cpu只有一个核心)
与并行的区别:在多核机器上,一个CPU执行一个任务,这些任务之间是并行。
时间分片(time slicing):处理器在不同的线程之间进行切换。
交错(interleaving):两个程序被转换为机器指令集A和B,A和B的元素(cpu指令)交替执行。
竞争(race condition):A和B是两个线程,A和B执行的交错会影响程序的正确性。
消息传递(message passing):模块之间进行信息传递。
线程安全(thread safe):ADT或方法在多线程中要执行正确 (不违反spec、保持RI ;与多少处理器、 OS如何调度线程;不会使spec增强)
限制共享(Confinement):线程之间不共享mutable数据类型(在线程内部使用局部变量,如果一个局部变量是一个对象引用,那么需要检查有没有在其他的线程中进行引用)(这个规则要求避免使用全局变量)。
关键问题
并发编程的两个程序之间如何进行交互?
(1)进行内存共享(shared memory)
两个处理器进行内存共享(运行时ADT)
两个程序访问一样的文件系统
两个线程,共享Java对象
(2)进行信息传递(message passing)
两台机器,通过网络通讯
同一台计算机上的两个程序,通过管道(ls|grep)连接进行通讯。
为什么要进行多线程编程呢?
为了充分利用cpu多核的特性(就是不让cpu的核心闲置,每一个特定时间只执行一个线程,就失去了多核的意义)。
为什么不能杀死线程呢?
会让共享data陷入不确定状态(因为线程之间是共享数据的,而且你杀死线程的时候也不知道这个线程是运行到了哪里)。
线程安全的四种操作是什么?
限制数据共享,共享不可变数据,共享线程安全的可变数据,采取同步机制(变并行为串行)。
在线程安全的四种操作中,他们之间控制的范围是不是有重叠呢?
没有,限制数据共享说的是ADT没有rep的时候,也就是最原始的情况;如果你想用immutable类型的rep,那么就是策略二的范围了,共享不可变数据,也就是你的rep前面加一个final(当然是举个例子,还有其他方法);如果一定要使用mutable的数据类型,那么就使用java API(与synchronizedCollection有关),但是在这样的API上,使用iterator也是不安全的。
immutability的定义呢?
没有mutator方法,所有的rep都是private和final的,没有表示泄露,没有mutation(像beneficent mutation这样的也不行),不允许子类重写方法。
关键操作
开启一个线程(两种方法)
(1)从Thread类派生子类
重写thread的run方法,调用start方法
public class HelloThread extends Thread {
    public void run() {
        //在这里加入你想要实现的内容
        }
    }

public static void main(String args[]) { 
    (new HelloThread()).start(); 
}

(2)从Runnable接口构造Thread对象
实现runna接口,将一个新的实例传给thread的构造函数,调用的新的thread实例的start方法

public class HelloRunnable implements Runnable {
    public void run() { 
        //在这里加入你想要实现的内容
    }
}

public static void main(String args[]) { 
        (new Thread(new HelloRunnable())).start(); 
}

使用一些方法影响线程之间的interleaving关系
Thread.sleep() 进入休眠的线程不会失去对现有monitor或锁的所有权。
Thread.interrupt() 会向Thread发送信号,但是只有在thread在sleep的时候才会接受interrupt信号,发送的信号如果没有被接受会保留,知道遇到sleep,interrupted或者线程结束。
Thread.interrupted() 检测有没有interrupt信号。
Thread.yield() 在run方法中调用,将cpu的控制权交出。
join() 阻塞线程。
知识point
Java虚拟机只运行单一进程(可以创建进程)。
java.util.concurrent是java并发包。
多线程和多进程之间共享处理器是通过时间分片完成的。
时间分片是OS自动调度的,也就是说一个正在执行的线程随时可能暂停,随时可能重新开始。
在多线程的任务中,因为共享memory,所以交错有可能造成错误。
交错产生错误的结果指的是违反了后置条件和不变量。
单行、单挑语句都未必是原子的,是否原子,由JVM确定 。
消息传递的时候的消息队列必须是java程序,不是原子操作。
消息传递机制无法解决竞争条件问题 。
sleep,interrupted,join都会检测线程是否收到interrupt信号。
iterator不是线程安全的。
java不会保证一个线程中发生的assignment会立即被另外一个线程看到,他有可能被临时地存储起来。
HashMap是线程不安全的,因为put方法。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值