import sun.applet.Main;
import java.security.PrivateKey;
/**
* @author
* @create 2021-01-14 22:35
*/
class ThreadDemo implements Runnable {
private int ticket = 100;
@Override
public void run() {
while (true) {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + ":卖票票号为" + ticket);
ticket--;
} else {
break;
}
}
}
}
class ThreadText {
public static void main(String[] args) {
ThreadDemo threadDemo = new ThreadDemo();
Thread thread1 = new Thread(threadDemo);
Thread thread2 = new Thread(threadDemo);
Thread thread3 = new Thread(threadDemo);
thread1.setName("窗口1");
thread2.setName("窗口2");
thread3.setName("窗口3");
thread1.start();
thread2.start();
thread3.start();
}
}
方式一 同步代码块
synchronized (同步监视器){
//需要被同步的代码
}
@Override
public void run() {
while (true) {
synchronized (ThreadDemo.class){
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + ":卖票票号为" + ticket);
ticket--;
} else {
break;
}
}
}
}
- 操作共享数据的代码,即为同步代码,不能包裹多也能包裹少
- 同步监视器:俗称所lock,任何类的对象都可以充当锁,
- 要求:多个线程必须共用一把锁
方式二 同步方法
同步方法仍然涉及同步监视器,只是不需要显示声明
package com.company;
class ThreadDemo implements Runnable{
private int ticket = 100;
@Override
public void run() {
while (ticket>0) {
showTicket();
}
}
//同步方法
private synchronized void showTicket() {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + ":票号" + ticket);
ticket--;
}
}
}
public class Main {
public static void main(String[] args) {
ThreadDemo threadDemo = new ThreadDemo();
Thread thread1 = new Thread(threadDemo);
Thread thread2 = new Thread(threadDemo);
Thread thread3 = new Thread(threadDemo);
thread1.setName("窗口1");
thread2.setName("窗口2");
thread3.setName("窗口3");
thread1.start();
thread2.start();
thread3.start();
}
}
jdk1.5解决线程安全问题lock方式
package com.company;
import java.util.concurrent.locks.ReentrantLock;
class ThreadDemo implements Runnable{
private int ticket = 100;
//实例化 ReentrantLock,使用锁, true表示公平锁,可不加
private ReentrantLock lock = new ReentrantLock(true);
@Override
public void run() {
while (ticket>0) {
try {
//用锁
lock.lock();
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + ":票号" + ticket);
ticket--;
} else {
break;
}
} finally {
//解锁
lock.unlock();
}
}
}
}
public class Main {
public static void main(String[] args) {
ThreadDemo threadDemo = new ThreadDemo();
Thread thread1 = new Thread(threadDemo);
Thread thread2 = new Thread(threadDemo);
Thread thread3 = new Thread(threadDemo);
thread1.setName("窗口1");
thread2.setName("窗口2");
thread3.setName("窗口3");
thread1.start();
thread2.start();
thread3.start();
}
}
线程通信交替打印
notify()唤醒线程
wait() 阻塞,并且释放锁,只能在同步代码块中使用