何时使用线程
1、多任务模式
一个会议软件进程中可以视频,可以打字,可以画图。
2、同时处理多个相同的任务
当一个线程顺序执行多次轮寻画图的任务,每次轮训需要执行画图的任务越多,耗时越长。开启多线程后,单个线程只运行某一部分,这样多个线程同时开工就会快。
3、流水线模式
完成一个完整的任务链,单个线程只负责一部分任务。
任务A完成,才能完成任务B,任务B完成才能执行任务C。
总结起来就是 多任务(不管相同还是不同)、流水线。如果考虑并发安全的问题,那么就要在平衡资源了,毕竟加锁也会有所消耗。
class Task{
int num = 1;
boolean flag1 = false;
boolean flag2 = false;
boolean flag3 = false;
public void taskA() {
flag1 = true;
num *= 200;
}
public void taskB() {
flag2 = true;
num /= 2;
}
public void taskC() {
flag3 = true;
num += 600;
}
}
class T1 extends Thread{
Task t;
T1(Task t){
this.t = t;
}
public void run() {
while(true) {
if(!t.flag2 && !t.flag3) {
t.taskA();
break;
}
}
}
}
class T2 extends Thread{
Task t;
T2(Task t){
this.t = t;
}
public void run() {
while(t.flag1) {
t.taskB();
break;
}
}
}
class T3 extends Thread{
Task t;
T3(Task t){
this.t = t;
}
public void run() {
while(t.flag2) {
t.taskC();
break;
}
}
}
并发处理任务
导致线程安全的事件:
多个线程操作同一资源,引起线程内存中操作出现重复
如果对于资源的操作:
读读 不会产生线程安全问题
读写 会产生
写写 会产生
所操作的资源在堆内存中,每个线程要对其进行修改就要先复制到栈中进行修改,然后返回去,这其中如果被其他线程也给修改了好多次,那么这个资源的状态就是未知的了,这时这个线程再给它赋值就不一定对了,这就触发了线程安全。
若要解决线程安全问题可以对资源进行上锁,防止线程安全问题发生
同步代码块:锁住资源,只让当前持有监视器锁的线程访问资源
public class Task2 extends Thread{
static int num = 0;
static Object object = new Object();
public void run() {
for(int i = 0; i < 10000; ++i) {
try {
Thread.sleep(1);
} catch (Exception e) {
// TODO: handle exception
throw new RuntimeException(e);
}
synchronized (object) {
++num;
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Task2 task1 = new Task2();
Task2 task2 = new Task2();
Task2 task3 = new Task2();
long start = System.currentTimeMillis();
task1.start();
task2.start();
task3.start();
try {
task1.join();
task2.join();
task3.join();
} catch (Exception e) {
// TODO: handle exception
throw new RuntimeException (e);
}
long end = System.currentTimeMillis();
System.out.println ("耗时:"+(end-start)+"ms");
System.out.println(num);
}
}