Java Foundation Day 19 Summary - multithreading 2

table of Contents:

First, the threads of the statement cycle

Second, thread synchronization

Communications Third, thread

Four, JDK5.0 way to create a new thread

/*-------------------------split line--------------------- - * /

First, the threads of the statement cycle

JDK with Thread.State class defines several state of a thread

To achieve multi-threaded, you must create a new thread object in the main thread. Jaba language using the Thread class and subclass of an object to represent the thread in one of its full life cycle usually involves the following fifth state:

1. New: when an object or a Thread class and subclass created is declared, the nascent thread objects in the new state

2. Ready: the thread in the new state is start (after), will enter the queue of threads waiting for CPU time slice, at this time it has with the conditions of operation, but not assigned to CPU resources

3. Run: When ready thread is scheduled and access to CPU resources, it went into operation, run () method defines the operations and functions of the thread

4. blockage: in certain special cases, to be suspended or artificially perform input and output operation, so that the CPU and temporarily terminates its own execution, to enter the blocked state

5. Death: thread to complete all of its work in advance or thread is mandatory termination or abnormal lead to an end

 

 

 

 

 

Second, thread synchronization

synchronized to use

Java security issues for multi-threaded to provide a professional solution: synchronization mechanisms

1. The sync block:

sychronized (object) {

// the code to be synchronized;

}

2.sychronized method can also be placed in a statement, it represents the entire approach to synchronization method.

E.g:

public sychronized void show(String name){

......

}

 

 Synchronization mechanism in the lock

Synchronization lock mechanism:

What synchronized locks are?

> Any object can be used as synchronization lock. All objects are automatically contain a single lock (monitor).

> Lock synchronization methods: static methods (class name .class), non-static method (this)

> 同步代码块:自己指定,很多时候也是指定为this或类名.class

 

注意:

> 必须确保使用同一个资源的多个线程共用一把锁,保证共享资源的安全

> 一个线程类中的所有静态方法共用同一把锁(类名.class),所有非静态方法共用同一把锁(this),同步代码块(指定需谨慎)

 

同步的范围

一、如何找问题,即代码是否存在线程安全?(重要)

1.明确哪些代码是多线程运行的代码

2.明确多个线程是否有共享数据

3.明确多线程运行代码中是否有多条语句操作共享数据

 

二、如何解决呢?(重要)

对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行。

即所有操作共享数据的这些语句都要放在同步范围中。

 

三、切记:

范围太小:没锁住所有有安全问题的代码

范围太大:没发挥多线程的功能

 

释放锁的操作

> 当前线程的同步方法、同步代码块执行结束

> 当前线程在同步代码块、同步方法中遇到break、return终止了改代码快、该方法的继续执行。

> 当前线程在同步代码块、同步方法中出现了未处理的Error或Exception,导致异常结束

> 当前线程在同步代码块、同步方法中执行了线程对象的wait()方法,当前线程暂停,并释放锁。

 

不会释放锁的操作

> 线程执行同步代码块或同步方法时,程序调用Thread.sleep()、Thread.yied()方法暂停当前线程的执行

> 线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放锁(同步监视器)。

应尽量避免使用supend()和resume()来控制线程

 

线程的死锁问题

死锁

互相占用对方所需要的同步资源、形成死锁。出现死锁不会有提示,只是所有线程都处于阻塞状态,无法继续。

 

解决方法:

专门的算法、原则

尽量减少同步资源的定义

尽量避免嵌套同步

 

Lock(锁)

同步锁使用Lock对象充当

java.utilconcurrent.locks.Lock接口是孔志多个线程对共享资源进行访问的工具。线程开始访问共享资源之前应先获得Lock对象。

ReentrantLock类实现了Lock,它拥有与synchronized相同的并发性和内存语义,在实现线程安全的孔志中,比较常用的是ReentrantLock,可以显式加锁、释放锁。

 

 synchronized与Lock的对比

1.Lock是显示锁(手动开启和关闭锁,别忘记关闭锁),synchronized是隐式锁,出了作用域自动释放

2.Lock只有代码块锁,synchroized有代码块锁和方法锁

3.使用Lock锁,JVM将花费较少的时间来调度线程,性能更好。并且具有更好的扩展性(提供更多的子类)

 

有限使用顺序:

Lock->同步代码块(进入方法体,分配了资源)-> 同步方法(在方法体外)

 

三、线程的通信

wait()与notify()和notifyAlll()

wait():另当前线程挂起并放弃cpu、同步资源并等待其他线程调用notify或notify方法换下,唤醒后等待重新获得对监视器的所有权后才能继续执行。

notify():唤醒等待同步资源的线程中优先级最高者

notifyAll():唤醒等待资源的所有线程

 

这三个方法只有在synchronized方法或synchronized代码块中才能使用,否则会报java.lang.lllegalMonitorStateException异常

因为这三个方法必须有锁对象调用,而任意对象都可以作为synchronized的同步锁,因此这三个方法只能在Object类中声明

 

wait()方法

对象名.wait()

使当前线程进入等待状态,直到另一个线程对该对象发出notify或notifyAll为止

调用方法的必要条件:当前线程必须具有对该对象的监控全(加锁)

调用此方法后,当前线程将释放对象监控权,然后进入等待

在当前线程被notify后,要重新获得监控权,然后从断点处继续代码的执行

 

notify()/notifyAll()

在当前线程中调用方法:对象名.notify()

功能:唤醒等待该对象监控权的一个/所有线程

调用方法的必要条件:当前线程必须具有对该对象的监控权(加锁)

 

四、JDK5.0新增线程创建方式

新增方式一:实现Callble接口

与使用Runnable相比,Callble功能更强大些

相比run方法,可以有返回值

方法可以抛出异常

支持泛型的返回值

需要借助FutureTask类,比如获取返回结果

 

Futrue接口

可以对具体Runnable、Callable任务的执行结果进行取消、查询是否完成、获取结果等

FutrueTask是Futrue接口的唯一的实现类

FutrueTask同时实现了Runnable,Futrue接口。它既可以作为Runnable被线程执行,又可以作为Futrue得到Callable的返回值

 

新增方式二:使用线程池

背景:并发情况下的线程,经常创建销毁使用量特别大的资源,对性能影响很大

思路:提前创建好多个线程,放入线程池中,使用时获取,使用完放回池中类似公共bus

 

好处

提高响应速度

降低资源消耗

便于线程管理

corePoolSize:核心池的大小

maximumPoolSize:最大线程数

keepAliveTime:线程没有任务时最多保持多长时间后会终止

。。。

Guess you like

Origin www.cnblogs.com/zhoutie170821/p/12002780.html