超级微信服务端项目
Java阶段的终结者!完成代码(前17条):
http://pan.baidu.com/s/1qXUgLGg
接口文档(转自优才陈军老师)
http://pan.baidu.com/s/1c16iJFq
测试数据数据表:
http://pan.baidu.com/s/1o7C9WOa
线程是开发中应用非常频繁的技术。在企业面试中也常被临幸。
进程是具有一定独立功能的应用程序关于某个数据集合上的一次运行活动,它是一个动态的概念。进程是系统进行资源分配和调度的一个独立单位。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响。一个进程至少有一个线程。
线程是进程的一个实体,是CPU调度和分配的基本单位,线程基本上不拥有系统资源,只拥有一点在运行过程中必不可少的资源(如堆和栈),但是它可与同属一个进程的其他线程共享进程所拥有的全部资源。线程的划分尺度小于进程,使得多线程程序的并发性高。
守护线程是一个特殊的线程,Daemon线程的作用是在程序的运行期间该线程在后台提供一种服务。它只有在所有的非Daemon线程运行结束时,Daemon线程也会中止运行。如JVM中的垃圾处理机制就是一个典型的Daemon。
public class Test01_DaemonThread {
public static void main(String[] args) {
DaemonThread daemon = new DaemonThread();
daemon.setDaemon(true);// 设置为守护程序
daemon.start();
Thread t = new Thread();
t.start();
Scanner scanner = new Scanner(System.in);
final String str = scanner.nextLine();// 阻塞主线程
scanner.close();
new Thread(){// 创建匿名内部类的对象
@Override
public void run() {
while(!str.equals("q")){
System.out.println("工作线程运行中...");
try {
Thread.sleep(1000*1);// 线程休眠 1000ms=1s
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
static class DaemonThread extends Thread{// 内部类
@Override
public void run() {
System.out.println("守护线程启动");
}
}
}
1、new-新建状态:创建了一个线程对象后,该线程就处于新建状态,此时线程还未启动。
2、Runnable–就绪状态:线程排队等待CPU分配运行时间。
3、Running-运行(正在运行)状态:线程获取了CPU分配的时间片段,则进入Running状态,开始执行run()方法中的代码。
4、Block-阻塞(挂起)状态:线程在执行过程中会被中断,目的是让其它线程获得执行的机会。阻塞结束时,该线程将进入Runnable状态,而非直接进入Running状态。
5、Dead-死亡状态:当线程的run()方法执行结束,线程进入Dead状态,对象将被垃圾回收,不可再回到Runnable状态。
阻塞是指暂停一个线程的执行以等待某个条件发生(如某资源就绪)
* sleep()和interrupt():使线程沉睡固定的毫秒时间,然后再进入Runnable状态,也可以使用interrupt()方法提前唤醒线程
public class Test02_SleepAndInterrupt {
public static void main(String[] args) {
Thread t = new Thread(){// 匿名内部类(继承自Thread)对象
public void run() {
while(true){
System.out.println("小白在睡觉....");
try {
Thread.sleep(1000*60*10);// 线程休眠10分钟
} catch (InterruptedException e) {// 休眠线程被interrupt唤醒时将报异常
System.out.println("是谁唤醒了我?!");
}
}
}
};
t.start();// 启动线程
while(true){
String str = new Scanner(System.in).nextLine();// 创建匿名Scanner对象
System.out.println("苏醒吧,小白!");
t.interrupt();// 唤醒休眠中的线程
}
}
}
public class Test05_Synchronized {
static Integer money = 1000;// 公共变量
public static void main(String[] args) {
// 创建3个线程
User xiaobai = new User("xiaobai");
User jia = new User("路人甲");
User yi = new User("路人乙");
// 开启3个线程
xiaobai.start();
jia.start();
yi.start();
}
static class User extends Thread{
public User(String name){
super(name);
}
@Override
public void run() {
// 如果不加锁,三个对象同时访问money,可能出现-200结果
synchronized(money){// 加锁
if(money >= 400){
System.out.println(Thread.currentThread().getName()+"取出了400元。");
money -= 400;
System.out.println("还剩"+money+"元。");
}else{
System.out.println("余额不足");
}
}
}
}
}
public class Test06_WaitAndNotify {
public static void main(String[] args) {
Thread t = new Thread(){
@Override
public void run() {
System.out.println("小白睡觉.....");
synchronized(this){// 对象锁
try {
wait();// 阻塞线程
} catch (InterruptedException e) {
e.printStackTrace();
}
// 唤醒后,顺序执行下面的代码
System.out.println("是谁呼唤我?!");
}
}
};
t.start();
Scanner scanner = new Scanner(System.in);
System.out.println("输入任意字符串,召唤小白!");
String str = scanner.nextLine();
synchronized(t){
t.notify();// 唤醒线程
}
}
}
public class Test04_Join {
static int result = 0;
public static void main(String[] args) {
Thread t = new Thread(){
@Override
public void run() {
for(int i=0;i<=10;i++){// 从1加到10
result+=i;
}
}
};
t.start();
try {
t.join();// 临界同步,t为子线程,main线程为父线程
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(result);// 55
}
}
生产者-消费者模型是一个典型的运用线程同步机制的模型。在生产者-消费者模型中通过创建两个线程来描述线程的同步机制。一个线程模拟生产者,负责提供任务;一个线程模拟消费者,负责执行任务;任务存放在一个公共的集合中。
为什么使用生产者-消费者模型?
生产者-消费者模型是一种典型的运用了线程同步机制的模型,是一种高复用松耦合的模型。在许多情况下我们在使用多线程时会遇到线程运行时间差的问题,这种异步操作我们就可以使用生产者-消费者模型来解决。
如何实现生产者-消费者模型?
1、创建一个线程负责提供执行的任务:生产者
2、创建一个线程负责执行任务:消费者
3、任务存放在一个公用的集合中:仓储
// 简单的模拟
public class Test07_CreatorAndCustomer {
static List tasks = new ArrayList();
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
// 消费者线程
Thread t1 = new Thread(){
@Override
public void run() {
boolean flag = false;
while(true){
try {
Thread.sleep(1000*60*60);
} catch (InterruptedException e) {
String s = "";
for(int i=0;i<100000;i++){
s+="a";
}// 模拟延迟执行
while(!tasks.isEmpty()){// 模拟消费者消费
String str = tasks.remove(0);
if(str.equals("q")){// 退出方式
flag = true;
break;
}
System.out.println(str);
}
}
if(flag){// 结束线程
break;
}
}
System.out.println("消费者线程结束!");
}
};
t1.start();
// 生产者线程
Thread t2 = new Thread(){
@Override
public void run() {
while(true){
System.out.println("请输入字符串:");
String str = scanner.nextLine();
tasks.add(str);
t1.interrupt();
}
}
};
t2.setDaemon(true);// 设置为守护程序,当消费者线程结束时,生产者线程也将中止
t2.start();
}
}
设计4个线程,2个线程每次对j增加1,2个线程对j每次减少1。
public class HomeWork {
private static int j;
public static void main(String[] args) {
for(int i=0;i<2;i++){// 调用四个线程对j操作
Thread t1 = new Thread(new Thread_Inc());
Thread t2 = new Thread(new Thread_Dec());
t1.start();
t2.start();
}
}
private static synchronized void inc(){ // 方法加锁,避免异步问题
j++;
System.out.println("j+1="+j);
}
private static synchronized void dec(){ // 可以实验不加锁时的情况,与加锁的进行比较
j--;
System.out.println("j-1="+j);
}
static class Thread_Inc extends Thread{// 内部类,+
@Override
public void run() {
for(int i=0;i<5;i++){
inc();
}
}
}
static class Thread_Dec extends Thread{// 内部类,-
@Override
public void run() {
for(int i=0;i<5;i++){
dec();
}
}
}
}