先讲如何通信: 再讲 如何 同步。网上的代码是有问题的。我注释了出来。
第一 。\线程 共用 一个 稀缺变量:
1、 继承至 thread 类
public
class
Innersharethread {
public
static
void
main(String[] args) {
Mythread mythread =
new
Mythread();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
}
}
class
Mythread {
int
index =
0
;
private
class
InnerThread
extends
Thread {
public synchronized
void
run() { //这是不同步的!!!这里的synchronized 加不加 结果都不能同步,因为加的位置不对。同步请见后面。
//线程很随意的就可以拿到index;
while
(
true
) {
System.out.println(Thread.currentThread().getName() +
"is running and index is "
+ index++);
}
}
}
public
Thread getThread() {
return
new
InnerThread();
}
}
2、通过实现Runnable接口实现线程的共享变量
public
class
Interfacaesharethread {
public
static
void
main(String[] args) {
Mythread mythread =
new
Mythread();
new
Thread(mythread).start();
new
Thread(mythread).start();
new
Thread(mythread).start();
new
Thread(mythread).start();
}
}
/* 实现Runnable接口 */
class Mythread implements Runnable {
int index = 0;
public synchronized void run() {//这是不同步的!!这里加上 synchronized 就便成只有0号线程再跑了,其他的都没法获得资源。
//可是如果不加,大家都可以随意抢夺index,无法同步
while (true)
System.out.println(Thread.currentThread().getName() + "is running and the index is " + index++);
}
}
第二种,通过pipe 的方式,这种方式只能一个负责输出,一个负责接收。这样单向的。
public
class
CommunicateWhitPiping {
public
static
void
main(String[] args) {
/**
* 创建管道输出流
*/
PipedOutputStream pos =
new
PipedOutputStream();
/**
* 创建管道输入流
*/
PipedInputStream pis =
new
PipedInputStream();
try
{
/**
* 将管道输入流与输出流连接 此过程也可通过重载的构造函数来实现
*/
pos.connect(pis);
}
catch
(IOException e) {
e.printStackTrace();
}
/**
* 创建生产者线程
*/
Producer p =
new
Producer(pos);
/**
* 创建消费者线程
*/
Consum c =
new
Consum(pis);
/**
* 启动线程
*/
p.start();
c.start();
}
}
/**
* 生产者线程(与一个管道输入流相关联)
*
*/
class
Producer
extends
Thread {
private
PipedOutputStream pos;
public
Producer(PipedOutputStream pos) {
this
.pos = pos;
}
public
void
run() {
int
i =
8
;
try
{
pos.write(i);
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
/**
* 消费者线程(与一个管道输入流相关联)
*
*/
class
Consum
extends
Thread {
private
PipedInputStream pis;
public
Consum(PipedInputStream pis) {
this
.pis = pis;
}
public
void
run() {
try
{
System.out.println(pis.read());
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
这样两种方式搞定了。后面会再写一篇socket 来实现多线程编程 和 python 在多线程上的实现。
第一例子:
1、相当于线程的工厂创造了四个相同的操作代码块,在每个线程自己私有空间里,所以加不加 synchronized (锁) 根本没用。
这里的想法是要锁住 稀缺资源 index;
2、synchronized 关键字不能加在 while 之外, 因为 加在那里,while没执行完毕,线程是不会放弃锁的。
正确的做法:
public
class
Innersharethread {
public
static
void
main(String[] args) {
Mythread mythread =
new
Mythread();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
}
}
class
Mythread {
int
index =
0
;
private
class
InnerThread
extends
Thread {
public
void
run() {
while
(
true
) {
synchronized (MyThread.this){//获得这个整个对象的锁
System.out.println(Thread.currentThread().getName() +
"is running and index is "
+ index++);
}
}
}
}
public
Thread getThread() {
return
new
InnerThread();
}
}
或者用 synchronized 锁住 争用资源的语句块。
如下,也是可行的:
public
class
Innersharethread {
public
static
void
main(String[] args) {
Mythread mythread =
new
Mythread();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
}
}
class
Mythread {
int
index =
0
;
public synchronized int add(){
return index++; // 锁住争用资源的语句块。
}
private
class
InnerThread
extends
Thread {
public
void
run() {
while
(
true
) {
System.out.println(Thread.currentThread().getName() +
"is running and index is "
+ add());
}
}
}
public
Thread getThread() {
return
new
InnerThread();
}
}
ok,后面的 runnable 的接口的更改方式我就直接给出答案了。也是一样的。
public
class
Interfacaesharethread {
public
static
void
main(String[] args) {
Mythread mythread =
new
Mythread();
new
Thread(mythread).start();
new
Thread(mythread).start();
new
Thread(mythread).start();
new
Thread(mythread).start();
}
}
/* 实现Runnable接口 */
class Mythread implements Runnable {
int index = 0;
public void run() {
while (true)
synchronized (this){ // 注意哈,这里的是this 不用在加 (类名.this)的格式了,因为主要是为了锁住稀缺资源,
//而第一例的实现是通过内部类来实现的,所以要拿到外部类的对象锁才行。
System.out.println(Thread.currentThread().getName() + "is running and the index is " + index++);
}
}
}
或者 :
class Mythread implements Runnable {
int index = 0;
public synchronized int add(){
return index++;
}
public void run() {
while (true)
System.out.println(Thread.currentThread().getName() + "is running and the index is " + add());
}
}
}