1.1 process and thread
1. Process and Thread进程和线程
(1) Relative drawing 关系图
(2) The JVM is a process
- run by default in one process (execute your code)
- work with several threads to achieve pseudo parallel processing or asynchronous behaviour
使用多个线程来实现伪并行处理或异步行为
- starting point is the main method
(3) Processes and threads
Processes | Thread | |
独立性 | runs independently isolated from other processes |
“lightweight process”, has its own call stack |
数据访问 | cannot directly access shared data in other processes |
can access shared data of other threads in the same process |
resources | resources of the process are allocated to it via the operating system |
has its own memory cache reads shared data->store this data in its own memory cache, reread the shared data |
2. Key Concepts in concurrent programming
(1)Atomicity 原子性
- 定义:when it cannot be interrupted
- 特点:Once it starts is always completes
- e.g. a = 5 (note: integer)(反例,a++ / a+=1 无atomic,因为可以分割成两个操作)
原子操作Atomic Operation(Tutorial):指不能被中断的操作
- x += 3; (等价于x = x + 3;)read-add-write_非原子操作
- x++;(等价于x = x + 1;)read-add-write_非原子操作
- X = new Integer(x); create-assign the reference_非原子操作
- x = y;(将y的值赋值给x)read-write_非原子操作
- x.equals(y);(比较x和y的值是否相等)_非原子操作
- x = 3;(将变量x的值设置为3)_原子操作
(2)Visibility 可见性
- 定义:when a thread must watch the actions of another thread
- e.g. for the termination of the thread; for a value being set
(3)Order of execution
- normal program:all you lines of code run in the same order every time.
- concurrent programming:The order of execution is not guaranteed!
public class Order implements Runnable {
public void run() {
String threadName = Thread.currentThread().getName();//获取当前线程的名字
System.out.println("I'm running in thread-" + threadName);
}
public static void main(String[] args) {
Order order = new Order();
for (int i = 0; i < 25; i++) {
Thread thread = new Thread(order);
thread.setName("Thread " + i);
thread.start();
}
}
}
//运行:每次的线程执行顺序不确定,因为the order is not gauranteed
运行程序(Tutorial):
public class MyThread extends Thread {
public void run() {
System.out.println(“I’m running”);
}
public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start();
System.out.println(“I’m not running”);
}
}
Prints “I’m running” and “I’m not running” in either order.
(4)Critical code
- 定义:A part of code that must only be executed by a single thread at one time
- e.g., writing to a file
3. Thread类
(1)作用
- executing your stuff in a thread(stuff is encapsulated in a run() method)在线程中执行你的东西
- manage the running of the thread 管理线程的运行
Two ways:
- Passing your class (with a run() method) into a new Thread object
- Extending the Thread class
The code that a thread executed is called within a run() method
(2)创建Thread方法1:Runnable接口
① 步骤:
- implements Runnable
- override run()
- in main(),new 创建的类的对象,new Thread对象(创建的类的对象参数)
- start()——run()
② 概念:
- Runnable:an interface that require you to implement a run() method
public class MyFirstThreadRunnable implements Runnable {
public void run() {
System.out.println("Entering thread using MyRunnable implements Runnable");
System.out.println("do some interesting stuff");
System.out.println("Leaving thread using MyRunnable implements Runnable");
}
public static void main(String[] args) {
MyFirstThreadRunnable myFirstThreadRunnable = new MyFirstThreadRunnable();
Thread thread = new Thread(myFirstThreadRunnable);
thread.start();
}
}
You do not need to define a class you can do all of that inline:
Thread t = new Thread(new Runnable(){ public void run() { // stuff here
}});
t.start();
(3)创建Thread方法2:继承Thread对象
步骤:
- extends Thread
- override run()
- in main, new 创建的类的对象
- start()——run()
public class MyFirstThreadExtend extends Thread {
public void run() {
System.out.println("Entering thread using MyThread extends Thread");
System.out.println("do some interesting stuff");
System.out.println("Leaving thread using MyThread extends Thread");
}
public static void main(String[] args) {
MyFirstThreadExtend myFirstThreadExtend = new MyFirstThreadExtend();
myFirstThreadExtend.start();
}
}
(4)两种方法的比较
-
Method 1 is better:
Extend:no other classes can be inherited by MyThread
Implement:allow a subclass of Thread to be used
public class RunOrStart implements Runnable {
public void run() {
System.out.println("this is the run method");
}
public void start() {
System.out.println("this is the start method");
}
public static void main(String[] args) {
RunOrStart myFirstThreadRunnable = new RunOrStart();
Thread thread = new Thread(myFirstThreadRunnable);
thread.start();//调用run方法
thread.run();//同样调用run方法
}
}
4. Controlling your thread
- Making your thread sleep
- Interrupting your thread’s sleep
- This is necessary:
- To make code execute at the appropriate time
- To manage resources
(1) sleep()方法
- Thread.sleep(1000)——make a current thread sleep for a certain number of milliseconds
- 结果:thread-pause(suspend); free up CPU time for other threads;
- 注:cannot choose another thread you want to sleep
public class SleepyTest implements Runnable{
public void run(){
System.out.println("Hello everybody! I'm going to sleep for 3 seconds...");
try {
Thread.sleep(3000); //休眠3s
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Bye bye everybody!");
}
public static void main(String args[]){
//创建线程
SleepyTest testThread = new SleepyTest();
Thread thread = new Thread(testThread);
//启动线程
thread.start();
}
}
public class Sleep02 extends Thread {
public void run() {
for (int i = 1; i < 5; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
public static void main(String args[]) {
//创建线程
Sleep02 t1 = new Sleep02();
Sleep02 t2 = new Sleep02();
//启动线程1,2
t1.start();
t2.start();
}
}
public class SleepMessages {
public static void main(String args[]) throws InterruptedException {
String importantMessages[] = { "Mares eat oats", "Does eat oats", "Little lambs eat ivy","A kid will eat ivy too" };
for (int i = 0; i < importantMessages.length; i++) {//遍历数组
Thread.sleep(1000);//休眠1s
System.out.println(importantMessages[i]);
}
}
}
(2) Interrupting your thread’s sleep
InterruptedException:
- 发生:the exception is thrown when a thread is interrupted while sleeping
- 作用:deal with the interrupt elegantly
public void run(){
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
(3) Yield方法
- Thread.yield(); make the current thread suspend;
- 结果:CPU——given to some other runnable thread; thread——wait until the CPU becomes available again;
- 注:the executing thread is returned to the ready queue of the processor, wait for its next turn
public class Yield01 implements Runnable {
Thread t;
Yield01(String str) {//constructor
t = new Thread(this, str);//在Yield01类中定义了一个成员变量t
t.start();//调用run方法
}
public void run() {
for (int i = 0; i < 5; i++) {// 每五个线程就让步
if ((i % 5) == 0) {
System.out.println(Thread.currentThread().getName() + " yielding control...");
//导致当前正在执行的线程对象暂时暂停并允许其他线程执行
Thread.yield();
}
}
System.out.println(Thread.currentThread().getName() + " has finished executing.");
}
public static void main(String[] args) {
//main()方法中创建了三个Yield01对象,分别代表三个线程。每个对象在其构造函数中会创建一个对应的线程,并启动线程的执行。
new Yield01("Thread 1");
new Yield01("Thread 2");
new Yield01("Thread 3");
}
}
(4) Interrupt flag
- 存在: contained in thread object
- 运作: change it to true - interrupt the thread eg. t1.interrupt()
- check: true-finish the method immediately; false-continue as normal;
- 默认为false - 0,线程的运行并不会完全因为Interrupt flag的变化而停止,而是线程检测到Interrupt flag的变化后自行决定是否要停止进程
(5) How threads respond to interruptions?
① sleeping/waiting:
- break out the sleeping/waiting state;
- set the flag to false;
- throw InterruptionException(after throwing,the Interrupt flag will return to true)
② not sleeping/waiting:
- calling the interrupt() performs normal behaviour;
- doesn’t interrupt the thread but only sets the interrupt flag to true
(6) Why might we want to interrupt a thread?
- 原因:likely doing something that’s taking too long (blocked)
- Blocking: a thread is prevented from doing anything
- What if we were waiting for a thread to complete, but it had gone to sleep? –interrupt() it so we can continue
-
Reasons a thread may be blocked
· waiting for a monitor lock
· suspended by call to wait() [become runnable on a notify or notifyAll message ]
· sleep(), wait()/notify(): the most important of the situations
-
calling interrupt() on a thread: force a thread