1、使用 synchronized 关键字实现线程之间的互斥操作。
public synchronized void set(int data) {...}
public synchronized void get() {...}
- 使用如上方式可以实现写数据和读数据都为互斥操作,但有的时候是需要读操作之间不需要互斥,写操作需要互斥,则可以使用如下lock锁的方式来实现。
2、使用Lock接口实现线程之间的互斥操作,注意使用这种方式需要手动释放锁,否则会造成死锁现象。
private ReadWriteLock rwl = new ReentrantReadWriteLock();
public void set(int data) {
rwl.writeLock().lock();// 取到写锁
try {
System.out.println(Thread.currentThread().getName() + "准备写入数据");
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.data = data;
System.out.println(Thread.currentThread().getName() + "写入" + this.data);
} finally {
rwl.writeLock().unlock();// 释放写锁
}
}
public void get() {
rwl.readLock().lock();// 取到读锁
try {
System.out.println(Thread.currentThread().getName() + "准备读取数据");
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "读取" + this.data);
} finally {
rwl.readLock().unlock();// 释放读锁
}
}
使用lock则将读写操作分离开,很好的避免了读操作也互斥造成速度过慢的问题。
3、wait/notify/notifyAll
- wait/notify/notifyAll都只能在同步线程中使用。
- 当在多线程中判断条件是否变化时只能使用while来进行判断,不能使用if语句判断。
private String lock;
public Subtract(String lock) {
super();
this.lock = lock;
}
...
public void subtract() {
try {
synchronized (lock) {
if(ValueObject.list.size() == 0) {//将这里的if改成while即可保证不出现越界异常!!!!
System.out.println("wait begin ThreadName="
+ Thread.currentThread().getName());
lock.wait();
System.out.println("wait end ThreadName="
+ Thread.currentThread().getName());
}
ValueObject.list.remove(0);
System.out.println("list size=" + ValueObject.list.size());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
...
- Object类中与线程有关的方法:
- notify/notifyAll
- wait()/wait(long)
- java.lang.Thread中与线程相关的方法:
- sleep()/sleep(long)
- join()/suspend()/resume()等等
- 注意notify和wait的使用顺序
假设在线程A中执行wait(),在线程B中执行notify()。但如果线程B先执行了notify()然后结束了,线程A才去执行wait(),那此时,线程A将无法被正常唤醒了
Summary
自己对线程进行的一些总结,其中有些代码来源于网上其他童鞋的资料,如有侵权请联系我,谢谢