java多线程笔记01
普通方式加锁 synchronized
多线程判断用while,否则有虚假唤醒的问题
// 普通方式加锁 synchronized
public synchronized void increment(){
String threadName = Thread.currentThread().getName();
while (number !=0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
++number;
System.out.println(threadName + "-->" + number);
// 通知
this.notifyAll();
}
public synchronized void decrement(){
String threadName = Thread.currentThread().getName();
while (number == 0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
--number;
System.out.println(threadName + "-->" + number);
// 通知
this.notifyAll();
}
ReentrantLock 锁
//ReentrantLock 锁 -- 他还有读写锁,读可以所有的读,写只能一个写(互斥)
package com.cdinit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ShareData {
private int number = 0;
private Lock lock = new ReentrantLock(); // 1.new ReentrantLock
private Condition condition = lock.newCondition(); // 2. 获取newCondition
public void increment() {
String threadName = Thread.currentThread().getName();
// System.out.println("Increment Thread --> " + Thread.currentThread().getName());
lock.lock(); // 3.lock
try{
while (number != 0){
try {
condition.await(); // 注意是await
} catch (InterruptedException e) {
e.printStackTrace();
}
}
++number;
System.out.println(threadName + " increment-->" + number);
// 通知 必须获得锁
condition.signalAll();
}finally {
lock.unlock();
}
}
public void decrement() {
String threadName = Thread.currentThread().getName();
// System.out.println("Decrement Thread --> " + Thread.currentThread().getName());
lock.lock();
try{
while (number == 0){
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
--number;
System.out.println(threadName + " Decrement-->" + number);
// 通知 必须获得锁
condition.signalAll();
}finally {
lock.unlock();
}
}
}
package com.cdinit;
public class ApplicationMain {
public static void main(String[] args) {
ShareData shareData = new ShareData();
new Thread(() -> {
for(int i=0;i<100;i++){
shareData.decrement();
}
},"T1").start();
new Thread(() -> {
for(int i=0;i<100;i++){
shareData.increment();
}
},"T2").start();
new Thread(() -> {
for(int i=0;i<100;i++){
try {
Thread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
shareData.decrement();
}
},"T3").start();
new Thread(() -> {
for(int i=0;i<100;i++){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
shareData.increment();
}
},"T4").start();
}
}
锁静态方法就是锁.class ,锁普通方法是锁this
package com.cdinit;
import java.util.concurrent.TimeUnit;
class Phone {
public synchronized void sendSMS() throws Exception{
TimeUnit.SECONDS.sleep(2);
System.out.println("...sendSMS");
}
public synchronized void sendEmail() throws Exception{
System.out.println("...sendEmail");
}
public void openPad(){
System.out.println("...openPad");
}
public static void sendStaticsendSMS() throws Exception{
System.out.println("...sendStaticSMS");
}
public static void sendStaticsendEmail() throws Exception{
TimeUnit.SECONDS.sleep(4);
System.out.println("...sendStaticEmail");
}
}
class Lock_B{
public static void main(String[] args) throws Exception {
Phone phone = new Phone();
new Thread(()->{
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
},"A").start();
new Thread(()->{
try {
phone.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
},"B").start();
new Thread(()->{
try {
phone.openPad();
} catch (Exception e) {
e.printStackTrace();
}
},"C").start();
new Thread(()->{
try {
Phone.sendStaticsendEmail();
} catch (Exception e) {
e.printStackTrace();
}
},"C").start();
new Thread(()->{
try {
Phone.sendStaticsendSMS();
} catch (Exception e) {
e.printStackTrace();
}
},"C").start();
}
}
ReentrantLock可以做线程调度
package com.cdinit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class ShareDataSource{
private int number = 1;
private Lock lock = new ReentrantLock();
private Condition c1 = lock.newCondition();
private Condition c2 = lock.newCondition();
private Condition c3 = lock.newCondition();
public void print5(int totalLoop) throws InterruptedException {
lock.lock();
try{
//1 判读
while (number != 1){
c1.await();
}
//2 干活
for(int i=1;i<=5;i++){
System.out.println(Thread.currentThread().getName() + "-->" + i +", total--> "+ totalLoop);
}
//3 通知
number = 2;
c2.signal();
}finally {
lock.unlock();
}
}
public void print10(int totalLoop) throws InterruptedException {
lock.lock();
try{
//1 判读
while (number != 2){
c2.await();
}
//2 干活
for(int i=1;i<=10;i++){
System.out.println(Thread.currentThread().getName() + "--->" + i +", total"+ totalLoop);
}
//3 通知
number = 3;
c3.signal();
}finally {
lock.unlock();
}
}
public void print15(int totalLoop) throws InterruptedException {
lock.lock();
try{
//1 判读
while (number != 3){
c3.await();
}
//2 干活
for(int i=1;i<=15;i++){
System.out.println(Thread.currentThread().getName() + "--->" + i +", total"+ totalLoop);
}
//3 通知
number = 1;
c1.signal();
}finally {
lock.unlock();
}
}
}
public class SeqThread {
public static void main(String args[]) throws Exception{
ShareDataSource shareDataSource = new ShareDataSource();
new Thread(()->{
for(int i=0;i<10;i++){
try {
shareDataSource.print5(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"AA").start();
new Thread(()->{
for(int i=0;i<10;i++){
try {
shareDataSource.print10(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"BB").start();
new Thread(()->{
for(int i=0;i<10;i++){
try {
shareDataSource.print15(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"CC").start();
}
}