Java多线程(二)同步
- - CSDN博客编程语言推荐文章如果你的java基础较弱,或者不大了解java多线程请先看这篇文章 java多线程(一)线程定义、状态和属性. 同步一直是java多线程的难点,在我们做android开发时也很少应用,但这并不是我们不熟悉同步的理由. 希望这篇文章能使更多的人能够了解并且应用java的同步. 在多线程的应用中,两个或者两个以上的线程需要共享对同一个数据的存取.
多线程加锁,2种方式
1.同步代码块,使用的锁可以是任意对象,但是操作共享资源时,锁必须唯一!
2.同步函数,使用的锁是this!
package com.gc.thread;
public class SynchronizdMethod implements Runnable {
//共享资源
private int num = 1000;
//不同的线程进入不同的同步代码中,验证同步函数使用的锁与同步代码块的锁是否一致
//如果不一致,则会导致数据混乱!
boolean flag = true;
@Override
public void run() {
if(flag) {
//改变标记,当b线程开启后,执行run(),就会进入到同步函数中
flag = false;
while(true) {
//同步代码块。判断 num>0 和 num-- 都是对共享资源进行操作,所以要放在同步代码块中
synchronized(this) {
//只要本次的同步代码块中的代码没有执行完,其它线程无法进入,因为锁没有释放
if(num>0)
System.out.println(Thread.currentThread().getName() + ": code segment--->" + num--);
}
}
} else {
while(true)
anotherThread();
}
}
//同步函数---使用函数对操作共享资源的代码进行封装,再将锁声明在方法上
//使用的锁是this,即传入Thread构造函数中的Runnable子类对象
private synchronized void anotherThread() {
if(num>0)
System.out.println(Thread.currentThread().getName() + ": method--->" + num--);
}
}
开启多线程
package com.gc.thread;
public class Demo {
public static void main(String[] args) {
SynchronizdMethod runnable = new SynchronizdMethod();
//传入同一个Runnable接口子类对象,让多线程操作Runnable中封装的共享资源
Thread a = new Thread(runnable);
Thread b = new Thread(runnable);
//开启线程 【注意:一个线程只能调用1次start(),多次调用将抛"线程运行状态异常"】
a.start();
//让主线程睡眠一小会,让a线程先执行,a线程将执行同步代码块中的代码
try {
Thread.sleep(10);//主线程睡眠的目的:让a线程先进入到同步代码块中,将标记改为false
} catch (InterruptedException e) {
e.printStackTrace();
}
//a线程改变flag标记之后,再开启b线程,让b线程执行同步函数中的代码
b.start();
}
}