/**Kotlin Thread基本是沿用了Java的线程创建方式
 * 1）java.lang.Thread直接创建
 * 2）java.lang.Runnable创建
 * 3）kotlin函数创建（内部实际采用方式1创建）
 * inline修饰的方法加入@Synchronized注解后，那么当inline方法被调用的时候，synchronized锁机制将会消失。
 */
import java.util.*
import kotlin.concurrent.thread
@Synchronized
fun synchronizedMethod() {
    println("inside a synchronized method: ${Thread.currentThread()}")
}

@Volatile
private var s = 1

fun main() {
    //继承 java.lang.Thread,重写 run 方法
    class MyThread : Thread() {
        override fun run() {
            s = 2
            synchronizedMethod()
            println("使用Therad类创建Thread")
        }
    }
    MyThread().start();
    //是上一种方式的Kotlin变种
    object : Thread() {
        override fun run() {
            s = 3
            synchronizedMethod()
            println("使用对象表达式创建Thread")
        }
    }.start()
    println("s=$s")

    //实现 java.lang.Runnable,重写 run 方法
    class MyRunnable : Runnable {
        override fun run() {
            s = 4
            println("使用Runnable创建Thread")
        }
    }
    Thread(MyRunnable()).start()
    //是Runnable方式的Kotlin变种
    Thread {
        s = 5
        println("通过Lambda表达式创建Thread")
    }.start()

    //Kotlin提供的专有函数来实现
    thread(start = true, isDaemon = false, name = "thread", priority = 3) {
        s = 6
        println("通过kotlin函数创建Thread")
    }
    println("s=$s")

    xproduce()
    xconsume()
}

//可以通过创建Object的实例，从而调用wait()、notify()、notifyAll()方法
private val lock = java.lang.Object()
var items=0
val maxItems=100
fun xproduce() = synchronized(lock) {
    while (items >= maxItems) {
        lock.wait()
    }
    Thread.sleep(Random().nextInt(100).toLong())
    items++
    println("Produced, count is $items: ${Thread.currentThread()}")
    lock.notifyAll()
}

fun xconsume() = synchronized(lock) {
    while (items <= 0) {
        lock.wait()
    }
    Thread.sleep(Random().nextInt(100).toLong())
    items--
    println("Consumed, count is $items: ${Thread.currentThread()}")
    lock.notifyAll()
}
