问题描述
package com.zzf.thread;public class Test_03 {public static void main(String[] args) {// TODO 自动生成方法存根TxtThread tt = new TxtThread();new Thread(tt).start();new Thread(tt).start();new Thread(tt).start();new Thread(tt).start();}}class TxtThread implements Runnable {int num = 20;String str = new String();public void run() {while (true) {synchronized (str) {//这里的锁?if (num > 0) {try {Thread.sleep(10);} catch (Exception e) {e.getMessage();}System.out.println(Thread.currentThread().getName()+ "this is " + num--);}}}}}输出结果:Thread-0this is 20Thread-0this is 19Thread-0this is 18Thread-0this is 17Thread-0this is 16Thread-0this is 15Thread-0this is 14Thread-0this is 13Thread-0this is 12Thread-0this is 11Thread-0this is 10Thread-0this is 9Thread-3this is 8Thread-3this is 7Thread-3this is 6Thread-3this is 5Thread-3this is 4Thread-3this is 3Thread-3this is 2Thread-3this is 1我不明白的是:TxtThread也是一个类,每创建一个它的对象就会拥有它的属性,因此num,str不是共享的,不存在访问冲突的情况 另外代码中synchronized (str) //这里获取的锁是哪一个对象的?我不是太懂synchronized的使用方法和原理
解决方案
TxtThread tt = new TxtThread();new Thread(tt).start();new Thread(tt).start();new Thread(tt).start();new Thread(tt).start();这段代码的意思是,新建一个线程对象TxtThread ,可以理解成一个普通的对象,只是拥有一个run的方法而已。而后面new Thread(tt).start();表示新建线程且执行tt对象的run代码块,所以你后面的每个线程都共享tt线程的变量,即tt对象的属性,是同步资源,那么访问他们,可能就会有同步问题而你在方法中 synchronized (str) {//这里的锁? 是str对象锁,下一个线程B访问就不能再次获取str的锁,必须等待前一个A线程执行完毕或者释放str锁时,才能让后续线程获取锁,并执行!
解决方案二:
int num = 20; String str = new String(); 是tt对象全局变量,是你所建线程共享的。 synchronized (str) {//这里的锁? 这个是str对象锁,因为str是共享的,所以是同一把锁。
解决方案三:
tt对象是共享的!
解决方案四:
同步锁锁定的是STR,不是NUM,NUM是临界资源……
解决方案五:
TxtThread tt = new TxtThread(); // 这里只创建一次啊 new Thread(tt).start(); new Thread(tt).start(); new Thread(tt).start(); new Thread(tt).start(); // synchronized 用法,网上一大堆。