Java多线程的思路就是一个:如果保证线程之间能够协作

首先我们得了解什么叫作线程,我们电脑里面有很多程序在运行,比如说QQ,微信等等,一个程序就是一个进程,进程是电脑分配内存空间的最小单位,但是进程里面有很多线程,比如说QQ,QQ里面有接受消息的,有显示动画的,有发送消息的,有很多很多线程,线程就是CPU执行命令的最小单位,一个CPU在一个时间内只能执行一个线程的任务

线程可以生成,运行,杀死,让其休眠.我们可以巧妙使用线程来完成许多协作的问题

我们可以构建线程池:如果有大量的任务要运行,会导致频繁创建新线程、销毁线程。线程池维护多个创建好的线程,同时可以让多个任务“复用”线程,避免了线程的重复创建和销毁。

我们还可以给资源上锁

可以使用synchronized(this) { …}给()里面的资源上锁,通过加锁:一个线程要进入同步方法,首先拿到锁,进入方法后立刻上锁,导致其他要进入这个方法的线程被阻塞(等待锁):表达式expr求值结果必须是一个对象的引用,因此可以通过对任何对象加锁来同步语句块,如果expr指向的对象没有被加锁,则第一个执行到同步块的线程对该对象加锁,线程执行该语句块,然后解锁;如果expr指向的对象已经加了锁,则执行到同步块的其它线程将被阻塞.expr指向的对象解锁后,所有等待该对象锁的线程都被唤醒,注意只是执行到同步块的线程加锁,而且如果同步块不是静态上下文的话就只对这个对象加锁

2. 给定下列程序:
public class Holder {
	private int data = 0;
	public int getData () {return data;}
	public synchronized void inc (int amount) {
		int newValue = data + amount;
		try {Thread.sleep(5);
		} catch (InterruptedException e) {}
		data = newValue;
	}
	public void dec (int amount) {
		int newValue = data - amount;
		try {Thread.sleep(1);
		} catch (InterruptedException e) {}
		data = newValue;
	}
}
public static void main (String [] args) {
	ExecutorService es = Executors.newCachedThreadPool();
	Holder holder = new Holder ();
	int incAmount = 10, decAmount = 5, loops = 100;
	Runnable incTask = () -> holder.inc(incAmount);
	Runnable decTask = () -> holder.dec(decAmount);
	for (int i = 0; i < loops; i++) {
		es. execute(incTask);
		es. execute(decTask);
	}
	es. shutdown ();
	while (! es. isTerminated ()) {}
}
下列说法正确的是_____A______。
A. 当一个线程进入holder对象的inc方法后,holder对象被锁住,因此其他线程不能进入inc方法和dec方法
B. 当一个线程进入holder对象的inc方法后,holder对象被锁住,因此其他线程不能进入inc方法,但可以进入dec方法
C. 当一个线程进入holder对象的dec方法后,holder对象被锁住,因此其他线程不能进入dec方法和inc方法
D. 当一个线程进入holder对象的dec方法后,holder对象被锁住,因此其他线程不能进入dec方法,但可以进入inc方法

当然可以使用lock.lock()和unlock()方法给this加锁

还可以使用Condition类来加锁,注意一定要声明锁才能使用Condition里面的await和signalALL方法,这个可以进行线程协作和信号通信

还有多线程的请求是并发的不是串行的,对于并发的请求,可以构建一个List来进行处理

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ReusableThread extends Thread{
//private Runnable runTask = null; //保存接受的线程任务
//使用一个列表接收所有需要完成的任务
private LinkedList<Runnable> tasks = new LinkedList<>();
private static Lock lock = new ReentrantLock();
private static Condition waitTask = lock.newCondition();

//只定义不带参数的构造函数
public ReusableThread(){
    super();
}

/**
* 覆盖Thread类的run方法
*/
@Override
public void run() {
while (true) {
lock.lock();
try{
if (tasks.size() == 0) {
try {
waitTask.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//移除并获取列表第一个任务,运行
tasks.removeFirst().run();
}finally {
lock.unlock();
}
}
}

/**
* 提交新的任务
* @param task 要提交的任务
*/
public void submit(Runnable task){
lock.lock();
try{
tasks.add(task);
waitTask.signalAll();
}finally {
lock.unlock();
}

}
public static void main(String[] args){
Runnable task1 = new Runnable() {
@Override
public void run() {
System.out.println("Thread " + Thread.currentThread().getId() + 
": is running " + toString());
try { Thread.sleep(200); }
catch (InterruptedException e) { e.printStackTrace(); }
}
@Override
public String toString() {
return "task1";
}
};
Runnable task2 = new Runnable() {
@Override
public void run() {
System.out.println("Thread " + Thread.currentThread().getId() + 
" is running " + toString());
try { Thread.sleep(100); }
catch (InterruptedException e) { e.printStackTrace(); }
}
@Override
public String toString() {
return "task2";
}

0 条评论

发表评论

邮箱地址不会被公开。 必填项已用*标注