不忘初心 砥砺前行, Tomorrow Is Another Day !html
本文概要:java
概念:进程是程序的实体,是受操做系统管理的基本运行单元.编程
概念:操做系统中最小调度单元,一个进程能够拥有多个线程.bash
线程的建立有3种方式.多线程
这种方式的本质也是实现Runnable接口.当咱们调用start方法时,并不会当即执行线程里面代码,而只是将线程状态变为可执行状态,具体的执行时机由操做系统决定.并发
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("直接继承Thread,重写run方法");
}
public static void main(String[] args) {
new MyThread().start();
}
}
复制代码
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("实现Runnable接口,重写run方法");
}
public static void main(String[] args) {
new Thread(new MyRunnable()).start();
}
}
复制代码
相比Runnable的三大功能.异步
关于ExecutorService与Future相关知识,将在线程池一篇文中详细讲解.这里只须要知道Callable通常是和ExecutorService配合来使用的.ide
public class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("子线程正在干活");
Thread.sleep(3000);
return "实现Callable接口,重写Call方法";
}
public static void main(String[] args) throws Exception {
MyCallable myCallable = new MyCallable();
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<String> future = executorService.submit(myCallable);
executorService.shutdown();
Thread.sleep(1000);//模拟正在干活
System.out.println("主线程正在干活");
//阻塞当前线程,等待返回结果.
System.out.println("等待返回结果:" + future.get());
System.out.println("主线程全部的活都干完了");
}
}
//调用输出
子线程正在干活
主线程正在干活
等待返回结果:实现Callable接口,重写Call方法
主线程全部的活都干完了
复制代码
线程同步的目的就是为了防止当多个线程对同一个数据对象进行存储时,形成数据不一致的问题.函数
同步问题示例post
public class SyncThread extends Thread {
private static final String TAG = "SyncThread";
private Pay pay;
public SyncThread(String name, Pay pay) {
super(name);
this.pay = pay;
}
@Override
public void run() {
while (isRunning) {
pay.count();
}
}
}
Pay.java
/**
* 未同步时
*/
public void count() {
if (count > 0) {
System.out.println(Thread.currentThread().getName() + ":>" + count--);
} else {
isRunning = false;
}
}
复制代码
//未使用同步时
D: 线程3:>912
D: 线程1:>911
D: 线程2:>911 //此时已经出现数据不同
D: 线程1:>909
D: 线程3:>910
D: 线程2:>908
D: 线程1:>907
D: 线程3:>906
D: 线程2:>905
D: 线程1:>904
D: 线程2:>903
D: 线程3:>903
D: 线程1:>902
D: 线程2:>901
D: 线程3:>900
//使用同步时
D: 线程1:>1000
D: 线程2:>999
D: 线程2:>998
D: 线程1:>997
D: 线程2:>996
D: 线程1:>995
D: 线程2:>994
D: 线程1:>993
D: 线程2:>992
D: 线程1:>991
D: 线程2:>990
D: 线程1:>989
D: 线程2:>988
D: 线程1:>987
D: 线程2:>986
D: 线程1:>985
D: 线程2:>984
D: 线程1:>983
复制代码
为了解决异步的问题,JAVA提供了锁的机制,synchronized 关键字.能够很方便的实现线程的同步.
先理解如何进行手动加锁,这样更容易理解自动加锁的机制.
伪代码
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition;
lock.lock();
try {
if(count == 0){
//进阻,放锁
condition.await();
}
//唤醒所以条件,而阻塞的全部线程
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
}finally{
lock.unlock();
}
复制代码
资源互斥,线程数据同步,提供了自动加锁.同步本质见java内存模型.
在实际开发中大多数状况使用同步方法与同步代码块,实现同步,除非一些须要高度控制锁的则使用重入锁和条件对象.
线程同步的四种方式.
1. 同步方法
private synchronized void countSyncMethod() {
if (count > 0) {
Log.d(TAG, Thread.currentThread().getName() + ":>" + count--);
} else {
isRunning = false;
}
}
复制代码
2. 同步代码块
private void countSyncCode() {
synchronized (this) {
if (count > 0) {
Log.d(TAG, Thread.currentThread().getName() + ":>" + count--);
} else {
isRunning = false;
}
}
}
复制代码
3. 使用重入锁
private void countSyncLock() {
mLock.lock();
try {
if (count > 0) {
Log.d(TAG, Thread.currentThread().getName() + ":>" + count--);
} else {
isRunning = false;
}
} catch (Exception e) {
e.printStackTrace();
}inally{
mLock.unlock();
}
}
复制代码
4. 使用特殊域变量(volatile)
先了解java内存模型与“三性”知识.
java内存模型定义了线程和主内存之间的抽象关系.
线程在对变量进行存与取时,通常先改变工做内存的变量值,再在某个时机刷新到主存中去.这样就会致使多线程并发时另外一个线程从主存中获取到的不必定是最新的值.
这样当一个共享变量被volatile修饰时.
private int x;
private int y;
//依赖自身
x++;
//依赖其余变量
if(x > y){
x = y;
}
复制代码
示例代码
@Override
public void run() {
//中断目标线程,并非指当即中止线程,而仅仅只是将线程的标识为true,通常由目标线程本身去检测并决定是否终止线程.
for (int j = 0; j <100000000 ; j++) {
if (Thread.currentThread().isInterrupted()){
System.out.println("Interrupted!已经中断中止输出.开始收尾工做1");
return;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
//处于阻塞状态的线程,也会立马被中断,因此就会抛出此异常.
System.out.println("Interrupted!已经中断中止输出.开始收尾工做2");
return;
}
System.out.println("还没中断继续输出j:" + j);
}
}
复制代码
关于Thread基础相关就介绍到这里了.接着下一篇介绍多线程编程中的线程池.Demo源码在最后一篇一块儿给出.
因为本人技术有限,若有错误的地方,麻烦你们给我提出来,本人不胜感激,你们一块儿学习进步.
参考连接: