- Java633
- Distributed189
- Tool133
- Spring102
- MQ89
- Netty88
- Log86
- File72
- RPC65
- SOFA65
- Concurrency60
- IM55
- Memory51
- Apache50
- Engine49
- Net49
- Design Pattern45
- Schedule40
- Lock33
- Basic32
- java31
- JVM26
- Dev24
- Protocol23
- Thread23
- System18
- Network17
- Web17
- SQL11
- Github10
- JMM10
- Jvm10
- Programming Language10
- SSO10
- Safe10
- System-Design10
- ORM10
- Base9
- Go9
- Maven9
- Pattern8
- Theory8
- WEB8
- TOOL7
- Auth6
- Architecture6
- HTTP6
- Python6
- CS4
- Mybatis4
- Concurrent3
- Exception3
- source-code3
- Framework2
- Gateway2
- Http2
- JMS2
- Security2
- Cache2
- DEV1
- Dotnet1
- IO1
- IOC1
- IOS1
- IoT1
- JDBC1
- Best Practice1
- Mybaits1
- PHP1
- Source Code1
- Dubbo1
- MVC1
Threads often have to coordinate their actions. The most common coordination idiom is the guarded block.
Such a block begins by polling a condition that must be true before the block can proceed. There are a number of steps to follow in order to do this correctly.
Let's use guarded blocks to create a Producer-Consumer application.
In concurrent programming, there are two basic units of execution: processes and threads.
A process has a self-contained execution environment. Threads are sometimes called lightweight processes. Both processes and threads provide an execution environment, but creating a new thread requires fewer resources than creating a new process.
线程的概念
线程 是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。
每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序。当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。
当 Java 虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的 main 方法)。Java 虚拟机会继续执行线程,直到下列任一情况出现时为止:
实现线程的方式,上一章中已经提到。下面使用实现Runnable的方式
/**
* Created by 侯彬彬 on 2016/4/14.
*/
public class NumCounter implements Runnable {
private static int count = 0;
private final int id = count++; //
protected int size = 5; //默认计算数量
public NumCounter() {
}
public NumCounter(int size) {
this.size = size;
}
/**
* 当前状态
*/
protected void status() {
System.out.println("#"+id+" count: " + size);
}
@Override
public void run() {
while(size-- > 0) {
status();
}
System.out.println("#"+id+" counter has done!");
}
}
最近想写一个多线程的程序,发现对于 java 的多线程理解还是不够深入。
所以看下源码,学习下基础知识。
接口
作用
接口作为绝对的抽象,非常便于后期拓展。
核心接口
- Runnable.java
public
interface Runnable {
/**
* When an object implementing interface Runnable is used
* to create a thread, starting the thread causes the object's
* run method to be called in that separately executing
* thread.
*
* The general contract of the method run is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
上代码
public class Num {
private int num;
public int getNum() {
return num;
}
public int add(int num) {
this.num += num;
return this.num;
}
}
常言道,一图胜千言。
线程协作
我们前面讲到使用 synchronized
进行线程间的互斥。
这座桥,一次只能过一个人。
情景引入
使用程序模拟三个人频繁通过一个只允许通过一个人的门。
每次有人通过,人数统计便会增加。
每次通过,都会校验通过者的信息。
普通方式
定义
- Gate.java
定义接口。
/**
* 接口
* @author bbhou
*/
public interface Gate {
/**
* 对过门的人通过校验
* @param name 姓名
* @param address 地址
*/
void pass(String name, String address);
}
想破坏也破坏不了。
Immutable 可以确保实例状态不发生改变,访问这类实例时不需要执行耗时的互斥处理,可以提升性能。
实际案例
定义
- Person.java
不可变对象类
/**
* 不可变类
*
* @author bbhou
* @version 1.0.0
* @since 1.0.0
*/
public final class Person {
private final String name;
private final String address;
public Person(String name, String address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}