【高级程序设计】Week1 Threads and Concurrency

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;
  • doesnt 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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值