线程的同步
Posted yicurtain
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程的同步相关的知识,希望对你有一定的参考价值。
线程的同步
线程的生命周期
同步
在Java中,我们通过同步机制,来解决线程的安全问题。
方法一:同步代码块
synchronized(同步监视器){
需要被同步的代码
}
说明
-
操作共享数据的代码,即为需要被同步的代码
-
共享数据:多个线程共同操作的变量
-
同步监视器:俗称:锁。任何一个对象,都可以充当锁。
要求:多个线程必须公用同一把锁。
举例
package com.yicurtain.THREAD;
//三个窗口卖100张票,使用同步代码块解决线程的安全问题
class window implements Runnable{
private int ticket=100;
Object object=new Object();
@Override
public void run() {
while(true) {
synchronized (object) {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + ":" + ticket);
ticket--;
} else {
break;
}
}
}
}
}
public class WindowTest {
public static void main(String[] args) {
window window = new window();
Thread t1 = new Thread(window);
Thread t2 = new Thread(window);
Thread t3 = new Thread(window);
t1.setName("线程1");
t2.setName("线程2");
t3.setName("线程3");
t1.start();
t2.start();
t3.start();
}
}
方法二:同步方法
如果操作共享数据的代码完整的声明在一个方法中,我们不妨将此方法声明为同步的.
举例
package com.yicurtain.THREAD;
//三个窗口卖100张票,使用同步方法解决线程的安全问题
class window1 implements Runnable{
private int ticket=100;
Object object=new Object();
@Override
public void run() {
while(true) {
show();
}
}
public synchronized void show(){
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + ":" + ticket);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
ticket--;
}
}
}
public class WindowTest1 {
public static void main(String[] args) {
window1 window1 = new window1();
Thread t1 = new Thread(window1);
Thread t2 = new Thread(window1);
Thread t3 = new Thread(window1);
t1.setName("线程1");
t2.setName("线程2");
t3.setName("线程3");
t1.start();
t2.start();
t3.start();
}
}
总结
- 同步方法仍然涉及到同步监视器,只是不需要我们显示的声明。
- 非静态的同步方法,同步监视器是:this
- 静态的同步方法,同步监视器是:当前类本身
死锁
- 不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃
自己需要的同步资源,就形成了线程的死锁 - 出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于
阻塞状态,无法继续
方式三:lock锁
- 实例化Reentrantlock
- 将要执行的代码用try{lock.lock}-finally{lock.unlock}包住
- 然后执行
举例
package com.yicurtain.THREAD;
import java.util.concurrent.locks.ReentrantLock;
//三个窗口卖100张票,使用lock解决线程的安全问题
class window2 implements Runnable{
private int ticket=100;
ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while(true) {
try{
lock.lock();
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + ":" + ticket);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
ticket--;
} else {
break;
}
}finally {
lock.unlock();
}
}
}
}
public class WindowTest2 {
public static void main(String[] args) {
window2 window2 = new window2();
Thread t1 = new Thread(window2);
Thread t2 = new Thread(window2);
Thread t3 = new Thread(window2);
t1.setName("线程1");
t2.setName("线程2");
t3.setName("线程3");
t1.start();
t2.start();
t3.start();
}
}
以上是关于线程的同步的主要内容,如果未能解决你的问题,请参考以下文章